RFC 809
UCL facsimile system
RFC 809: UCL FACSIMILE SYSTEM ๐
Bestie, the title block is giving very important vibes. The author is Tawei Chang โจ, and the paper was written in the Department of Computer Science at University College London. It's an INDRA Note (1185) and is listed as a Working Paper, dated Feb. 1982. The original doesn't list anything it obsoletes or updates, so there's nothing to report there ๐ง
ABSTRACT: okay so this note is all about the computerised facsimile system the Department of Computer Science at UCL built ๐ First it looks at what the system can do and the experiments that went with it. Then it talks about the design rules it followed. Last, it covers how the system was actually implemented, and the full details live in the appendices ๐ซถ
NOTE: ๐ Figures 5 and 6 are available if you email a request to Ann Westine at USC-Information Sciences Institute, 4676 Admiralty Way, Marina del Rey, California, 90291 (or WESTINE@ISIF). Include your name and postal mailing address, and say you want figures 5 and 6 from RFC 809.
OR: ๐ป you can grab both figures online from these files on the SRI-NIC online library:
<NETINFO>RFC809a.FAX and <NETINFO>RFC809b.FAX
These files use the format described in RFC 769.
Here's the contents, bestie ๐
Contents
1. INTRODUCTION...........................................1
2. SYSTEM FUNCTIONS.......................................2
2.1 Communication......................................4
2.2 Interworking with Other Equipment..................8
2.2.1 Facsimile machines............................8
2.2.2 Output Devices................................9
2.3 Image Enhancement..................................11
2.4 Image Editing......................................15
2.5 Integration with Other Data Types..................16
3. SYSTEM ARCHITECTURE....................................17
3.1 System Requirements................................17
3.2 Hierarchical Model.................................19
3.3 Clean and Simple Interface.........................20
3.3.1 Principles....................................21
3.3.2 Synchronisation and Desynchronisation.........21
3.3.3 Data Transfer.................................22
3.4 Control and Organisation of the Tasks..............22
3.4.1 Command Language..............................23
3.4.2 Task Controller...............................23
3.5 Interface Routines.................................26
3.5.1 Sharable Control Structure....................26
3.5.2 Buffer Management.............................27
4. UCL FACSIMILE SYSTEM...................................28
4.1 Multi-Task Structure...............................29
4.2 The Devices........................................29
4.3 The Networks.......................................30
4.4 File System........................................31
4.5 Data Structure.....................................32
4.6 Data Conversion....................................34
4.7 Image Manipulation.................................35
4.8 Data Transmission..................................39
5. CONCLUSION.............................................41
5.1 Summary............................................41
5.2 Problems...........................................42
5.3 Future Study.......................................46
Appendix I: Devices
Appendix II: Task Controller and Task Processes
Appendix III: Utility and Data Formats
Reference
1. INTRODUCTION โจ
Okay, so the whole point of a facsimile system is to copy a document or image faithfully from one piece of paper onto another piece of paper that's sitting somewhere else ๐๐ธ For a long time, the main way to do fax has been over the telephone network. The thing is, most fax machines can't store a page or edit it before sending, and it's almost impossible for different brands of fax machine to talk to each other ๐ญ Honestly, fax machines are way behind other electronic communication services, and it's not a good look.
Connecting fax to computer communication techniques makes a huge difference ๐ฅ It isn't just about reliability and efficiency, though that's a win too. The really iconic part is that the computer lets a fax machine plug into a full message and information processing setup ๐ The computer's storage can hold tons of fax data and bring it back super fast. Data conversion lets different types of fax machines communicate with each other. And the fax image can be edited or combined with other kinds of data, like text, voice and graphics, to build a multi-media message that can be spread far and wide over computer networks ๐ฆ
So in the Department of Computer Science at UCL, they built a computerised facsimile system to put computer technology, especially communication, to full use in the fax world ๐ They've already done some work to improve fax service in several areas:
- Adaptation for computer networks. The fax machine can be used with computer networks. This makes document transmission more reliable and accurate, and it also improves normal point-to-point transfers โจ
- Storage of fax pages. Pages can be queued, which saves operator time. Standard documents can also be kept permanently and sent whenever you want ๐ง
- Interworking with other fax machines. Different makes of fax machine can swap images with each other ๐ซถ
- Compression of fax images. This allows more efficient transmission. Different compression schemes are being investigated ๐
- Display of images on other devices. A colour display shows the result of image processing very vividly ๐
- Improvement of images. The ability to "clean" fax images allows for an even higher compression ratio, and it also gives a better result at the destination ๐
- Editing of fax pages. You can change pictures, resize images and merge two or more images, all electronically ๐
- Integration with other data types. For now, coded character text can be converted into fax format, and mixed pages containing pictures and text can be manipulated ๐
This note first looks at what the facsimile system can do, and it covers the related experimental work too ๐ Then it discusses the design discipline behind the system. Finally, it describes how the UCL facsimile system was implemented. The appendices give the detailed description of the system, namely:
- I. Devices
- II. Task controller and task processes
- III. Utility routines and data format
2. SYSTEM FUNCTIONS โจ
The computerised facsimile system is built around an LSI-11 micro-computer running the MOS operating system [14], with two AED62 floppy disk drives [17], a Grinnell colour display [18], a DACOM facsimile machine [16], and a VDU as the system console ๐ป The LSI-11 is also hooked up to several networks, including the ARPANET/SATNET [21], [22] and the UCL Cambridge Ring. Here's a schematic of the system, shown in Fig. 1 ๐ฆ
facsimile machine bit-map display
+------+ +------+
! ! ! !
+------+ +------+
+------+ \ / VDU
! disk ! +----------+ +-----+
+------+ ---- ! LSI-11 ! -- ! !
! disk ! +----------+ +-----+
+------+ |
+------+
! NI !
+------+
Network Interface
Fig. 1 Schematic of UCL facsimile system
So here's how it works ๐ธ A page gets read on the fax machine, and the image data it makes is stored on a floppy disk. That data can be processed locally on the micro-computer, then sent to a file store on a remote computer across the network. At the remote site, the image data can be processed and printed on a fax machine.
It also works the other way around ๐ฅ The system can receive image data sent by a remote host on the network, and that data can be handled in exactly the same way, including being printed on the local machine.
Section 2.1 discusses the problems involved in sending fax image data over a network. The sections after it deal with working on image data locally ๐ง
To interwork with other fax machines, the image data has to be converted from one representation format to another. Interworking with other output devices means the image has to be scaled to fit the size of the destination device. These are covered in section 2.2 ๐
Being able to process images by computer opens the door to so many possibilities ๐ First, as covered in section 2.3, an image can be enhanced, which improves its quality and allows for more efficient storage and transmission. Second, a fax editing system can be supported, so a picture can be changed and/or combined with other pictures. This is described in section 2.4 โจ
Coded character text can also be turned into its bit-map representation, so it can be handled as a fax image and merged with pictures ๐ซถ This gives you an environment where multi-type information can be dealt with, and it's discussed in section 2.5 ๐
2.1 Communication ๐
The first goal of the computerised facsimile system is to use a computer network to send data between fax machines that are geographically separated ๐
Normally, fax machines are used with telephone equipment, and the data travels over telephone lines ๐ Putting fax machines on a computer network is a bit of a problem, though, because a fax machine can't use a computer network directly ๐ญ A computer is needed to handle the network tasks, so the first phase was to attach the fax machine to a computer. ๐
We had to build a special hardware interface so the fax machine could talk to a small computer ๐ This interface was made to look exactly like the telephone system to the fax machine. The computer was also programmed to act exactly like another fax machine sitting on the end of a phone line ๐ So the local fax machine just sent its data to the computer totally happily, thinking it was chatting with a remote fax machine on the other end of a phone wire. ๐ง Because of the property of the DACOM 6450 used in the experiment [16], the interface could be identical to one built for connecting to an X25 network. The binary synchronous mode of the chip used (SMC COM5025) was perfect for driving the DACOM machine ๐ฅ
On the other side of the computer network there was a similar computer with an identical fax machine. ๐ฆ Sending a fax picture now looked pretty simple: data got pulled from the fax machine into the computer, zoomed across the network like normal computer data, and then got sent from the computer to the fax machine at the far end โจ The data on the network looks exactly like any other computer data. There is nothing special about it that shows it came from a fax machine ๐ The schematic for this fax transfer system is in Fig. 2.
facsimile
machine
+---+ interface
! ! +--+ +-----+
! ! == ! ! == ! ! computer
+---+ +--+ +-----+
|
- - - - - - computer
/ \ network
\ / facsimile
- - - - - - machine
| interface +---+
+-----+ +--+ ! !
computer ! ! == ! ! == ! !
+-----+ +--+ +---+
Fig. 2 Facsimile transfer system
The experimental system was used for a joint experiment between UCL and two groups in the United States ๐ Pictures were exchanged over the ARPANET/SATNET [21], [22] between UCL in London, ISI in Los Angeles, and COMSAT in Washington D.C. (Fig. 3). This setup was chosen because there was no equivalent group available in the UK ๐ฌ๐ง
Okay, now the big problem with picture data is how much of it there is ๐ญ Even with data compression, a single page of fax data can make as much computer data as you'd need to send over 20,000 alphabetic characters, or over a dozen typed pages ๐ So for any number of pages put into the system, you get an immense amount of computer data. That means transmission is slower than sending text, and way more storage is needed to hold the data ๐ฆ
Another problem showed up super fast once we actually built this thing ๐ฅฒ The network we were using often couldn't keep up with the speed of the fax machine. When that happened, the computer tried to slow the fax machine down. The fax machine read this "slowness" as a communication problem (a telephone line would never act like that), and it would abandon the transfer halfway through the page ๐ค
US UK
satellite
COMSAT __
+---+ +--+ / \
! ! -- ! ! / \
+---+ +--+ / \
| \ / \
+---+ \ / \ UCL
!fax! \+--+/ \+--+ +---+
+---+ ARPANET ! ! SATNET ! ! -- ! !
/+--+ +--+ +---+
/ |
ISI / +---+
+---+ +--+ !fax!
! ! -- ! ! +---+
+---+ +--+
|
+---+
!fax!
+---+
Fig. 3. The three participants of the facsimile experiments
Why was this happening? Because the fax machine we used was never meant to be hooked up to a computer ๐ It was designed and built for telephone lines. Totally unaware that it was connected to a computer, the fax machine sent data at a constant rate, and that rate was higher than the network could accept. In other words, the computer network we were using was not designed for the transfer rate we were trying to push through it ๐ซ
Honestly, both of these problems are fixable โจ Fax machines are now coming onto the market that are designed to talk directly to a computer ๐ These machines don't mind the delays on the computer interface, and they're fine with stopping and restarting. Also, if fax machines were going to be seriously used on a computer network, the network could just be designed for the high data rate needed. Our problem got worse because we were using a network that was never designed for the data rates our usage needed ๐
Even though our problems came from the experimental equipment we were working with, we still had to make things better so we could have bigger, more extensive communications ๐ซถ The easiest fix was to add a local storage area in our computer where the data could be held before transmission ๐ Now a page gets transferred in three stages. First, the fax data is read from the fax machine and stored on a local disk. This happens at high speed because it's just a local operation ๐๏ธ Once that's done, the data is sent over the network to a disk on the remote computer. Finally, the data on that disk is output to the remote fax machine. This improved system is shown in Fig. 4.
computer network
fax computer - - - - computer fax
+---+ +-----+ / \ +-----+ +---+
! ! = ! ! = ==> = ! ! = ! !
+---+ +-----+ \ / +-----+ +---+
- - - + | - - - - | + - - >
| | + - - - - - - - - - + | |
| | | | | |
V | | V | |
+---+ +---+
! ! ! !
! ! ! !
+---+ +---+
disk disk
Fig. 4. The improved facsimile transfer system
The idea behind this method is to decouple the fax machine from the network communications ๐ง Data is read from the fax machine at full speed, without the delays the computer network would cause. This also makes it way nicer for the human operators, because each page is now read in less than a minute โฑ๏ธ Transmission over the network then happens at whatever speed the network can sustain. This doesn't affect the fax machines at all, because they aren't involved in the sending or receiving ๐ The remote fax machine only gets told the data is ready once all of the data has arrived at the remote disk. Then the fax machine gets the data as fast as it will accept it ๐จ
The downside of this system is that the person sending the pages doesn't know how long it'll take before they're actually printed on the other side ๐ฌ If the operator inputs several pages in quick succession, they get stored on disk, and it might take a while before the last page is actually delivered to its destination. Honestly, this isn't always a bad thing ๐ธ When lots of operators are sending data to the same destination, it's a definite win to be able to input pages and have the system deliver them once the destination is free ๐ That's way better than the current telephone system, where the operator has to keep re-dialing the remote fax machine until somebody picks up ๐๐
2.2 Interworking with Other Equipment โจ
2.2.1 Facsimile machines ๐จ๏ธ
As we mentioned earlier, fax machines produce a huge amount of data per page because of how the pages are encoded ๐ฉ To cut down on the data that has to be transmitted, various compression techniques are used. Fax machine manufacturers came up with their own proprietary ways of compressing and encoding the data ๐ Unfortunately, this meant different fax machines couldn't interwork at all ๐ In the system described in the last section, pictures could only be exchanged between sites that had identical fax machines. The new set of CCITT recommendations will reduce how much differences in equipment get in the way ๐
Having the data on a computer is iconic because we can manipulate it any way we want ๐งโโ๏ธ For example, we could convert data from the form used by one fax machine into the form another one needs. That means interworking between different types of fax machines can actually happen ๐
Developing this system happened in two stages: decompressing the fax data from the coded form used by our machine into an internal data form, and then recompressing the internal form into the encoded form the destination machine needs. Two programs were written to do these two operations ๐ป
At the same time, we were developing compression and decompression programs for machines that use other techniques ๐ฆ In particular, we developed programs to handle the recently approved CCITT recommendation for facsimile compression [15]. The CCITT came up with two varieties of compression, depending on the resolution being used. ๐
Unfortunately, bestie, there were no facsimile machines on the network that use the CCITT compression technique ๐ญ. The new methods still gave us two big wins ๐. First, it proved the data could be converted inside a small computer, so machines of different types could be supported on the network โจ. Second, it let us compare the compression results. You can read the details in [13] ๐.
Essentially, these showed that the DACOM technique our facsimile machine uses is comparatively poor ๐. Considerably less data needs to be transmitted if some other method is used ๐. This brings up another possibility: we could change the compression of the data to reduce the volume for transmission, then change the data back again at the destination ๐ฆ. This may save considerable transmission time, especially if fast computers or special hardware are easily available ๐. It hasn't been tried in our system yet, because none of the other users on the network can change the data format back into what their machines require ๐.
There are lots of other, more efficient compression schemes, e.g. block compression [7] and predictive compression [8] ๐ง . We just haven't incorporated them into our system yet ๐ธ.
2.2.2 Output Devices
One area we've explored is using devices other than facsimile machines to output the data ๐. Facsimile machines are both expensive to buy and relatively slow to operate ๐ฉ. So we looked into a TV-like screen to display the data, just like character VDUs are commonly used to show text ๐บ. This needs bit-map displays, with an address in memory for each position on the screen ๐. Full colour and multiple shades can be used too, as long as the bit-map storage is appropriately large ๐. It's simple in principle, but actually getting the techniques working took considerable effort ๐ค.
The problems come from the way the facsimile image is encoded ๐. Raw facsimile images are rows of small dots, each one recorded as a black or white space. When they're arranged together, they build up a picture, kind of like how a newspaper picture is made ๐๏ธ. The catch is that the number of dots on a facsimile page isn't the same as on most screens ๐ฌ. For instance, the DACOM facsimile machine uses 1726 dots across each page, but a screen usually has just 512 dots across ๐. So to show the picture on screen, the 1726 dots have to be squeezed into just 512 dots. Put another way, 1214 dots must be thrown away without losing the picture ๐ฑ!
It's reducing the number of picture elements that causes the trouble ๐ญ. We could just keep every third dot or so from the facsimile page and display only those. Or we could take three or more at a time and try to convert the group into a single black or white dot. Unfortunately, in both cases, data can get lost that is necessary to the picture ๐. For example, a facsimile encoding of an architect's drawing could easily end up with a complete line removed, totally changing how the image looks ๐๏ธ.
After lots of experimenting, we came up with a method for reducing the number of dots without destroying the picture ๐. It's a thinning technique, where key elements of the picture are thinned but not removed โจ. Sometimes, when the detail gets too fine, some elements get merged. But in those situations, the eye wouldn't have been able to see that detail anyway ๐. The details of this technique are described in [3] and [4] ๐.
It may also be required that a picture be enlarged ๐. This can be done by simply duplicating each pixel in the picture. For a non-integral ratio, the picture can be expanded up to the nearest integer and then shrunk to the correct size ๐. However, this method may degrade the image quality. For example, the oblique contour may become stepped, especially when the picture is enlarged too much ๐ต. This problem can be solved with an iterative enlargement algorithm ๐ช. Each time a pixel is replaced with a 2x2 array of pixels, and the pattern of that array depends on the original pixel and the pixels surrounding it ๐งฉ. This procedure is repeated until the requested ratio is reached ๐. If the ratio is not a power of 2, the same method as the one for non-integral ratios is used ๐ .
As a side effect of developing this technique, we could freely change the size and shape of an image ๐ฅณ. The picture can be expanded or shrunk, or it can be distorted. Distortion, where the horizontal and vertical dimensions of the image are changed by different amounts, is often useful in image editing ๐จ.
This ability to change the image size meant we could display the image on a screen as well as output it on a facsimile machine ๐ฅ๏ธ. For a user of a computerised facsimile system, this is a super useful feature ๐. Images can be displayed on screen much faster than on a facsimile machine, and displays are significantly cheaper than facsimile machines too ๐ค. An installation could have lots of screen displays where the image can be viewed, but maybe only one facsimile machine for hard copy ๐จ๏ธ. It's kind of like how many computer setups today have limited printers because of their cost, while display screens are way more numerous ๐ป.
2.3 Image Enhancement
One thing we really wanted to investigate was image enhancement ๐. Enhancing an image is a very tricky operation. As the name implies, it means the image is improved in some sense ๐ซ . But under program control, this is hard to achieve: what the program thinks is an improvement, a human might judge to be distinctly worse ๐ โโ๏ธ.
Our enhancement attempts were aimed especially at printed documents and other forms of typed text ๐. The experiment was double pronged: we hoped to make the image easier for humans to read, while also making it easier for the computer to handle ๐ง ๐.
In our earlier experiments, we'd noticed that the encoding of printed matter was often very poor ๐. This was especially noticeable when we enlarged an image. Instead of each character having smooth edges like the original document, the edges were very rough. Unexpected notches and excrescences were caused by the facsimile scanner ๐. They not only degrade the image quality, but also decrease the compression efficiency. A typical enlargement of several characters is shown in Fig. 5 ๐.
Fig 5. An enlargement of an typed text
The enhancement method we adopted was first employed at Loughborough University [5] ๐. This method smooths the edges of the dark areas on the image โจ. The technique considers each dot in the image in turn. The dot is either left as it is, or changed to the opposite colour (white to black or black to white), depending upon the eight dots that surround it ๐ฏ. The particular pattern of surrounding dots that is required to change the inner dot's colour controls the harshness of the algorithm [6], [8] ๐ถ๏ธ.
In our first set of experiments, the result was definitely worse than the original ๐ฌ. Square-like characters such as H, L, and T came out very well ๐. But anything with a slope (M, V, W, or S) became so bad that the oblique contours were stepped ๐. The method was then modified to produce a result that was far more acceptable. The image looked a lot cleaner than the original ๐งผ. Fig. 6 shows the same text as Fig. 5, but after it has been cleaned โจ.
Fig. 6 A cleaned text
The effect of these can be hard to see clearly ๐. So we used the colour on our Grinnell display to show the original picture and the outcome of various picture processing operations, superposed in different colours ๐. This brings out the effect of the operations very vividly ๐คฉ.
It was mentioned above that the enhancement was done not only to improve the image for reading, but also for easier processing by the computer ๐ป. As described earlier, the image from the facsimile machine is compressed in order to reduce the amount of data. The cleaning allows a higher compression rate, so more efficient transmission and/or storage can be achieved ๐.
We learned some important lessons from the enhancement exercise ๐. Originally, we thought the main attraction of enhancement would be improving readability. In the end, we found that improving readability was very difficult, especially because the facsimile image was so poor ๐ญ. Instead, we found that reducing the compressed output was more important ๐ . By reducing the data to be transmitted by a quarter, significant savings could be made ๐ค. But before such a technique could be used in a live system, the time it takes to produce the enhancement must be weighed against the time that would be saved in transmission โฑ๏ธ.
2.4 Image Editing
By editing, we mean that the facsimile picture can be changed, or combined with other pictures, while it's stored inside the computer ๐ช. Earlier we said we could change the size and shape of a facsimile image. That technique was later combined with an overlaying method that let one picture be combined with another [12] ๐ซถ.
To do any editing, the picture has to be displayed so the user can see it ๐. In our case, we displayed the picture on the bit-map screen ๐ฅ๏ธ. The image took up the left-hand side of the screen, and the right side was reserved for the picture being built ๐งฉ. The user could select an area of the left-hand screen and move it to a position on the right-hand screen ๐ฑ๏ธ. Several images could be displayed in succession on the left, with areas selected and moved to the right ๐. Finally, the right-hand screen could be printed on the facsimile machine ๐จ๏ธ๐.
Selecting an area of the picture was done with a coloured rectangular subsection ๐ช. It was controlled by a program in the computer and could be moved around on the screen ๐ฆ. The rectangular subsection
okay so the rectangle could be moved around with instructions the operator typed in ๐. It could go up or down, and it could get bigger or smaller, whatever they wanted. Once the right area was picked, the program remembered the coordinates and slid that coloured rectangle over to the right-hand side of the screen ๐ฆ. Then the user picked an area again, the same way. When they were done editing, the program cut the selected part out of the left-hand screen and reshaped it to fit the rectangle on the right-hand screen. Then the result got displayed so they could see it ๐โจ
When an image was being edited, the editor also had to keep a second scaled copy for display. Why? Bc the screen had different dimensions from the facsimile machine ๐ The actual editing stuff, like chopping and merging, happened on the original image data files at the full resolution the facsimile machine could handle ๐
2.5 Integration with Other Data Types โจ
the facsimile machine is lowkey so much more than just a fax input/output device ๐จ๏ธ๐ It can also work as a printer for other kinds of data, like coded character text and geometric graphics. Right now, text can be converted into facsimile format and printed on the machine. Mixed pages with pictures AND text can also be handled by our system ๐ Mixing facsimile images with geometric graphics is still a topic for future research, so that's a later glow-up ๐ฎ
To turn a character string into its facsimile format, the system keeps a translation table that stores the patterns of the characters available in the system, so they can be retrieved. The input string gets translated into a set of scan lines. Each scan line is made by joining together the matching character patterns from the string ๐งฉ
That translation table is basically a software font, and it can be edited and modified ๐๏ธ Only one font is available for now, but it's super easy to add other character fonts. And a font can even be loaded remotely from a database over the communication network ๐ฐ๏ธ๐
This opens up some really fun applications. For example, the machine could act as a Teletex printer, as long as the Teletex character font is included in the system. In that case, the text images might get distorted so they fit the presentation format the Teletex service asks for ๐ Similarly, Prestel viewdata pages could be displayed on the Grinnell screen ๐บโจ
Pictures can also be mixed with text by combining this text conversion with the editing from the previous section. This should be seen as a notable step towards multi-type processing ๐ฆ๐
And this doesn't just support a local multi-type environment. Multi-type information can also be sent over a network ๐ Right now, though, a mixed page with text and pictures can only be sent once it's been represented in a bit-map format ๐ฉ It would be way more efficient to send the text and the pictures separately, then rebuild the page at the destination site ๐ง That would need a multi-type data structure that both communicating sites understand, and that's the tea ๐ซ๐
3. SYSTEM ARCHITECTURE โจ
Now let's talk about the general design and implementation rules for a computerised facsimile system that does all the functions from the earlier sections ๐ We'll go over the system requirements first, then a hierarchical model where the modules on different layers each run as their own separate processes. After that comes the Clean and Simple interface used for inter-process communication, then the task controller (the boss that organises the tasks in a requested job), and finally some experimental work on a more convenient user programming environment and a more efficient data transfer method ๐ซถ
3.1 System Requirements
In a computerised facsimile system, images are stored in digital form ๐ข To make that happen, a page gets scanned by the optical scanner on the facsimile machine, and a digital number gets produced for how dark each pixel is ๐ค High resolution is needed to keep the detail, so facsimile data files are usually pretty chunky ๐ฐ To store and send them efficiently, the data has to be compressed as much as possible ๐ฆ
Right now, facsimile machines from different manufacturers have different properties, like different compression methods and different resolutions ๐ตโ๐ซ There are also some international standards for facsimile compression, used for data sent over the public data network. These mean the facsimile data has to be converted from one representation form to another, so people who are far apart and use different machines can still talk to each other ๐๐ And fancier stuff, like image editing, needs the system's processing facilities too ๐
When a facsimile image is being processed, it should be represented in a common format or internal data structure. That's what gets used to pass information between the different processing routines ๐ For convenience and efficiency, this internal structure should be pretty well compressed, and it should be easy for the computer to manipulate ๐ป In our experimental work, the line vector was picked as the standard unit, with a simple run-length compression used on it [3] ๐ง Some processing routines might use other data formats, like bit-map. But it's on those routines to convert between their format and the standard one ๐
The system should have several processing routines, and each one does one primitive task, like chopping, merging, or scale-changing โ๏ธ You can build a huge variety of processing operations as long as those task modules can be organised flexibly. Being able to organise tasks flexibly should be thought of as one of the most important requirements of the system ๐
One option is to run the processing routines separately, using temporary files as the communication media. It's very simple, but honestly it's far too inefficient ๐ญ
As mentioned above, the information unit for communication between processing routines is the line vector. That means the routines could be organised as embedded loops, where a routine takes its input line from the source routine in the inner loop and passes its output line to the destination routine in the outer loop [3]. Obviously this is pretty efficient! But it isn't realistic for our system, because building different processing loops at run-time is super hard, and flexible task organisation becomes impossible ๐ โโ๏ธ
In a real-time operating system environment, the primitive tasks can be implemented as separate processes. This approach gets discussed in detail in the following sections, and it gives us the flexibility we need ๐ฆโจ
3.2 Hierarchical Model
As shown in Fig. 7, the modules in a single computer fall into three layers ๐ง Here's the diagram:
+---------+
! ! task controller
+---------+
tasks
+---+ +---+ +---+ +---+ +---+
! ! ! ! ! ! ! ! !
+---+ +---+ +---+ +---+ +---+
| | |
+---+ +---+ +---+
! ! ! ! device drivers ! !
+---+ +---+ +---+
- - - | - - | - - - - - - - - - | - - - -
+---+ +---+ +---+
! ! ! ! physical | !
! ! ! ! devices ! !
+---+ +---+ +---+
Fig. 7 The hierarchical model
So here's the breakdown ๐
(1) Device Drivers, the lowest layer in the model. The modules here handle the I/O activity of physical devices, like the facsimile machine, the display, and the floppy disk ๐พ This layer takes the I/O programming burden off the task modules above it, which is honestly such a relief ๐
(2) Tasks, which do all the processing primitives and handle the different data structures ๐ ๏ธ Above each physical device's driver, there are one or more device-independent modules. They work as an information source or sink in the task chain (more on that below). A file system module lets other modules store and retrieve information on secondary storage, like a floppy disk ๐ Decompression and recompression routines convert the data structures of facsimile image information, so the facsimile machines can talk to the rest of the system ๐ Processing primitives, like chopping, merging, and scaling, are implemented as task modules in this layer. They're designed so they can be concatenated to carry out more complex jobs, which is giving Lego vibes ๐งฑ And as far as the system is concerned, the protocols for data transmission over computer networks are also treated as task modules in this layer ๐
(3) Task Controller, which organises the task processes to perform the specified job ๐ It gives application-layer users a procedure-oriented language, so they can define the requested job as a chain of task modules. The chain is literally represented by a character string:
<source_task>|{<processing_task>|}<sink_task>
Following a command like that, the task controller picks the relevant task modules and links them together in the proper order using logical links ๐ Then it runs the tasks on the chain under its control, so the data from the source gets processed and the result gets put into the sink ๐ซถ
3.3 Clean and Simple Interface โจ
3.3.1 Principles โจ
Okay so, in this app it's really important to build the software in a modular way ๐งฉ The plan is to put together a set of modules that each handle a different image processing task. Then there's another set of transport modules, which have to be built for shipping data over the different networks the UCL system is attached to. In our computerised facsimile system, these task modules are implemented as separate processes, and the whole system depends on those processes talking to each other. The interface they use for that was designed to be universal. It doesn't care which modules are on either end, and it's called the Clean and Simple interface [20]. This section is all about that interface ๐
The Clean and Simple interface handles the synchronisation and transfer of full-duplex data streams between two communicating processes ๐ฆ So it has three big parts: connection synchronisation, data transfer, and connection desynchronisation. We'll go through each one below.
A connection gets started by one of the two processes, and that one usually belongs to a higher layer. Like, the interface between protocols of different layers is always initiated by the higher layer, though sometimes the connection is started passively by the primitive 'listen'. You'll see in the next section that task processes can talk to each other through their connections to the higher layer (the task controller), and that's what makes flexible task organisation possible ๐
The process that starts the connection is called the 'master' process, and the other one is the 'slave' process. The master is also in charge of resource allocation for both processes. By 'resource' we mean mostly the memory areas for the message structure and the data buffer. Making the definition asymmetric like this means nobody gets confused about who allocates what ๐
The interface runs on the signal-wait mechanism the operating system provides. A data structure called CSB (Clean and Simple Block) holds the function, the data buffer, and other info, and it gets sent as the event message whenever one process signals another [20] ๐ฌ
3.3.2 Synchronisation and Desynchronisation ๐ค
Connection synchronisation happens in two steps. First, the two processes swap their identifiers for that specific connection using a getcid primitive. Usually the pointer to the task control structure of the process gets used as the connection identifier ๐ชช
Then the 'master' sends an open CSB with the appropriate parameter string, which passes the initialisation info. This info (also called the open parameter) depends on the process, or more accurately on the task. For example, the parameters for the file system should be the file name and the access mode. As long as the 'slave' accepts the request, the connection is established and data can be transferred through the interface ๐
To desynchronise the connection, the 'master' initiates a 'close' action. The 'slave' can also report an error state or an EOF (end of file) state to request a connection desynchronisation ๐
The listen primitive in our system is reserved for processes that receive a request from remote hosts on the networks ๐
3.3.3 Data Transfer ๐ฆ
While the Clean and Simple interface is asymmetric when it comes to connection synchronisation, data transfer is completely symmetric once the connection has been established. Data is allowed to flow in both directions, even though the operations are quite different ๐
There are two primitives for data transfer, read and write. To send some data to the 'slave', the 'master' signals it with a CSB containing the write function and a buffer filled with the data. After consuming the data, the 'slave' returns the CSB to report the result status of the transmission ๐
To go the other way and receive data from the 'slave', the 'master' uses a read CSB with an empty buffer. Once the 'slave' has the CSB, it fills the buffer with the data requested and then returns the CSB ๐
3.4 Control and Organisation of the Tasks ๐ง
Another big deal in the multi-process architecture of the UCL facsimile system is the need to systematise the control and organisation of the tasks. That's the job of the task controller, and this section covers how it works ๐
3.4.1 Command Language ๐ฌ
As mentioned earlier, the task controller supports a procedure-oriented language. That's how the user, or the routines of the upper layers, define the jobs they want. A command should contain the following information:
- the names of the task processes which are involved in the job.
- the open parameters for these task processes.
- the order in which the tasks are to be linked.
The last item is quite important, though usually the same order as the one given in the command gets used ๐ฏ
A command in this language is presented as a zero-ended character string. In the task name strings and the attribute strings of the open parameters, '|', '"', and ',' must be excluded, because they'll be treated as separators. Here's the definition below, where '|' (the separator of the command strings in the language) does not mean 'OR'. ๐
<command_string> ::= <task_string>
<command_string> ::= <task_string>|<command_string>
<task_string> ::= <task_name>
<task_string> ::= <task_name>"<open_parameter>
<open_parameter> ::= <attribute>
<open_parameter> ::= <attribute>,<open_parameter>
3.4.2 Task Controller ๐๏ธ
In our experimental work, the task controller module is called fitter. That name is borrowed from UNIX and kind of hints at how the module works. According to the command string, it links the specified tasks into a chain, and the data gets processed along that chain to fulfil the job requested (Fig. 8) โ๏ธ
tasks
+-----+ +-----+ +-----+
! a ! -> ! b ! -> ! c !
+-----+ +-----+ +-----+
Fig. 8 The task chain
Since all modules, including fitter itself, are implemented as processes, the connections between modules should be via the Clean and Simple interfaces. Upon receiving the command string, the fitter parses it to find each task process involved and opens a connection to it. Formally, the task processes are chained directly, but logically there's no direct connection between them. All of them are connected to the fitter (Fig. 9) ๐ธ๏ธ
fitter
+-------------+
+-- ! ! --+
| +-------------+ |
| | |
V V V
+-----+ +-----+ +-----+
! a ! ! b ! ! c !
+-----+ +-----+ +-----+
Fig. 9 The connection initiated by the fitter
For each of the processes it connects, the fitter keeps a table called pipe. When the command string is parsed, the pipe tables get double-linked to represent the specified order of data flow. For one process, its pipe table holds two pointers: a forward one pointing to its destination and a backward one pointing to its sources. Besides the pointers, it also keeps the info needed to identify the task process and the corresponding connection ๐๏ธ
Fig. 10 illustrates the chain of the pipe tables for the job "a|b|c". Note that the forward (output) chain ends at the sink, while the backward (input) chain ends at the source. In this sense, the task processes are chained in the specified order via the fitter (Fig. 11). The data transfer along the chain is initiated and controlled by the fitter, with each process getting the input from its source and putting the output to its destination ๐
+-----+ +-----+ +-----+
! * -+--> ! * -+--> ! 0 !
+-----+ +-----+ +-----+
! 0 ! <--+- * ! <--+- * !
+-----+ +-----+ +-----+
! a ! ! b ! ! c !
+-----+ +-----+ +-----+
! ! ! ! ! !
! ! ! ! ! !
+-----+ +-----+ +-----+
Fig. 10 The pipe chain
fitter
+-------------+
+-> ! * -> * -> * ! --+
| +-------------+ |
| | A |
| V | V
+-----+ +-----+ +-----+
! a ! ! b ! ! c !
+-----+ +-----+ +-----+
Fig. 11 The data flow
This strategy makes the task organisation so flexible that only the links have to be changed when a new task chain is to be built up. In such an environment, each task process can be implemented independently, provided the Clean and Simple interface is supported. This also makes extending the system quite easy ๐
The fitter manipulates one job at a time. But it must maintain a command queue to cope with the requests, which come simultaneously from either the upper level processes or other hosts on the network ๐
3.5 Interface Routines ๐ ๏ธ
In a modular, multi-process system such as the UCL facsimile system, the structure of the interface routines is very important. The CSI of section 3.3 is fundamental to the modular interface, and a common control structure is also essential. This section gives some details about both the sharable control structure and the buffer management ๐งฐ
3.5.1 Sharable Control Structure ๐
Though the CSI specification is straightforward, the implementation of the inter-process communication interface may be rather tedious, especially in our system, where there are many task processes to be written. Not only does each process have to implement the same control structure for signal handling, but the buffer management routines must also be included in all the processes ๐ญ
The 'csinit' primitive is called for a task process to check in ๐ง An information table gets allocated, and the pointer to that table is returned to the caller as the task identifier. That identifier is what you use for every call to these interface routines ๐. Each task process then waits by invoking the csopen primitive ๐ค, which does not return until the calling process is scheduled. Once the connection between the process and the fitter is established, the call returns the pointer to the open parameter string of the task, and the corresponding task gets started ๐ฆ. A typical structure of the task process (written in C) looks like this:
static int mytid; /* task identifier */
task()
{
char *op; /* open parameter */
mytid = csinit();
for(;;) {
op = csopen(mytid);
... /* the body of the task */
}
}
After the task program runs, the process calls csopen and waits again ๐ The portability of the task routines is improved by a huge amount ๐ Only the interface routines should be changed if the system were to run in a different operating environment ๐ธ
3.5.2 Buffer Management ๐
The package of interface routines also gives you universal buffer management, so the task processes are freed from that burden ๐ซถ The allocation of the data buffers is the responsibility of the higher level process, the fitter. If the task processes allocated their own buffers, some redundant copying would have to happen ๐ฉ So the primitives for data transfer, csread and cswrite, are designed like this:
char *csread(tid, need);
char *cswrite(tid, need);
Here tid is the identifier of the task and need is the number of data bytes to be transferred. The primitives return the pointer to the area that satisfies the caller's requirement. csread returns an area containing the data the caller asked for. cswrite returns an area where the caller can copy the data to be transferred. The copied data gets written to its destination at a proper time, without the caller having to do anything ๐
Obviously, the unnecessary copy operations can be avoided โจ It is recommended that the data buffer returned by the primitives be used directly to attain higher performance ๐
To make this work, each time a piece of data is required, the size of the buffer needed is compared with the size of the unused buffer area in the current CSB. If the unused area is not less than the needed size, the current buffer pointer is returned ๐ Otherwise, a temporary buffer has to be employed. The data is copied into the buffer until the requested size is reached. In this case, the temporary buffer is returned instead of a part of the current buffer ๐ง
A cswrite call with the need field set to zero tells the interface routine that no more data will be sent ๐ That causes a close CSB to be sent to the destination routine.
If there is not enough data available, csread returns zero to indicate the end of data ๐
4. UCL FACSIMILE SYSTEM ๐
Now we get into the implementation of the computerised facsimile system developed in the Department of Computer Science at UCL ๐
This system has several components ๐งฉ Since the total system is a modular and multi-process one, a specific system must be built up for a specific application. The way that this is done is discussed in section 4.1. The specific devices and their drivers are described in section 4.2. The system can be attached to a number of networks. In the UCL configuration, the network interface can be direct to SATNET [22], SERC NET [23], PSS [24], and the Cambridge Ring. The form of network connection is discussed further in section 4.3. The system must transfer data between the facsimile devices and the disks, and between the networks and the disks. For this, a filing system is required, which is discussed in section 4.4.
A key aspect of the UCL system is flexibility of devices, networks, and data formats ๐ The flexibility of devices is achieved by the modular nature of the device drivers (section 4.2). The flexibility of network is discussed in section 4.8. The additional flexibility of data structure is described in section 4.5. The flexibility can be utilised by incorporating conversion routines as in section 4.6. An important aspect of the UCL system is the ability to provide local manipulation facilities for the graphics files ๐ผ๏ธ The facilities implemented for local manipulation are discussed in section 4.7. In order to transfer files over the different networks of section 4.3., a high level data transmission protocol must be defined. The procedures used in the UCL system are discussed in section 4.8. ๐ฆ
4.1 Multi-Task Structure ๐งฉ
The task controller and processing tasks are implemented as MOS processes. A number of utility routines are provided for users to build new task processes and modules at application level ๐ ๏ธ
In the environment of MOS, a process is included in a system by specifying a Process Control Table when the system is built up. The macro setpcte is used for this purpose, and the meaning of its parameters is defined in [14].
#define setpcte(name,entry,pridev,prodev,stklen,
relpid,relopc)
{0,name,entry,pridev,prodev,stklen,relpid,relopc}
A Device Control Table (DCT) has to be specified for each device when the system is built up. A DCT can be defined anywhere, since devices are referenced by the DCT address ๐ The macro setdcte is designed to declare devices, and the meanings of its parameters are specified in [14]. This method is used in the device descriptions ๐
#define setdcte(name,intvec,devcsr,devbuf,devinit,
ioinit,intrpt,mate)
{04037,intrpt,0,0,name,mate,intvec,devinit,
devcsr,devbuf,ioinit}
4.2 The Devices ๐
As mentioned in section 2, apart from the general purpose system console, there are three devices in the system to support the facsimile service. These are:
(1) AED62 Floppy Disk, which is used as the secondary memory storing the facsimile image data. Above its driver, a file system is implemented to manage the data stored on the disks, so that an image data file can be accessed through the Clean and Simple interface. This file system is discussed in detail in the next section. For some processing jobs, the image data has to be buffered on a temporary file, lest time-out occurs on the facsimile machine ๐พ
(2) DACOM Facsimile Machine, which is used to input and output image data. It reads an image and creates the corresponding data stream. On the other hand, it accepts the image data and reproduces the corresponding image. Above its driver, there is an interface task to fit the facsimile machine into the system, with the Clean and Simple interface being supported. The encoding algorithm for the DACOM machine is described in [19] ๐
(3) Grinnell Colour Display, which is used as the monitor of the system. Above its driver, an interface task is implemented so that the image data in standard format can be accepted through the Clean and Simple interface ๐
The detailed description of these devices can be found in Appendix 1. The interface task and the description for each device are listed in the following table. The interface tasks can be directly used as data source or sink in a task string ๐ง
Device Interface Task Description
AED62 Floppy Disk fs() aed62(device)
DACOM fax Machine fax() dacom(device)
Grinnell Display grinnell() grinnell(device)
Note that the DCTs for the facsimile machine and Grinnell display have been included in the corresponding interface tasks, so there is no need to declare them if these tasks are used ๐
4.3 The Networks ๐
There are three relevant wide-area networks terminating in the Department of Computer Science at the end of 1981. These are:
(1) A British Telecom X25 network (PSS, [24]).
(2) A private X25 network (SERC NET, [23]).
(3) A Defence network (ARPANET/SATNET, [21], [22]).
In addition, there is a Cambridge Ring as a local network ๐
For the time being, the UCL facsimile system is directly attached to the various networks at the point NI (Network Interface) of Fig. 1 ๐
As mentioned earlier, pictures can be exchanged via the SATNET/ARPANET, between UCL in London, ISI in Los Angeles, and COMSAT in Washington D.C.. The Network Independent File Transfer Protocol (NIFTP, [9]) is used to transfer the image data ๐ฐ๏ธ This protocol has been implemented on LSI under MOS [10]. In addition, we at UCL have put NIFTP on an ARPANET TOPS-20 host, which can act as an Internet File Forwader (IFF). In this case, TCP/IP ([28], [29]) is employed as the underlying transport service. Since TCP provides reliable communication channels, the provision of checkpoints and error-recovery procedures are not included in our NIFTP implementations ๐
In the X25 network, the transport procedure is NITS/X25 ([25], [26]). Though pictures can be transferred to the X25 networks, no experimental work has been done, because:
(1) There is at present no collaborative partner on these networks.
(2) The LSI-11, on which our system is implemented, has no direct connection to these networks ๐
Locally, image data can be transmitted to the PDP11-44s running the UNIX time-sharing operating system. At present, the SCP ring-driver software uses permanent virtual circuits (PVCs) to connect the various computers on the ring ๐
4.4 File System ๐๏ธ
A file system has been designed, based on the AED62 double density floppy disk, for use under MOS. It is itself implemented as a MOS process supporting the Clean and Simple interface. The description of this task, fs(fax), can be found in Appendix 2 โจ
In a command string, the file system task is picky ๐ : it can only be the data source or the data sink, so it has to sit at the very first or very last spot. If it's first, the file gets read. If it's last, the file gets written ๐.
There are three access modes:
- Read a file
- Create a file
- Append a file
The file name and access mode are passed in as the open parameters โจ.
Let's walk through one, because it's so iconic ๐ฆ. Say you want to read a document on the facsimile machine and save the data stream it creates onto the file system. The command string you need is:
fax"r|fs"c,doc
where: fax - interface task for facsimile machine r - read from facsimile machine fs - file system task c - create a new file doc - the name of the file to be created.
Wanna dump a file instead? Meet od() ๐ง. It's a task process that works as a data sink in a command string.
4.5 Data Structure ๐ธ
Facsimile image data comes from a high-resolution raster scanner, so the original picture can be reproduced faithfully. The data represents binary images: monochrome, with two levels of intensity, which makes it bit-mapped graphics ๐ค๐ค.
The simplest version is the bit-map itself. Each bit is one picture element, lined up in the same order the original picture gets scanned, with 1s for black pixels and 0s for white ones. Editing is easy-peasy: two images in bit-map format can be merged with a simple logic OR operation, and any specific pixel can be grabbed with a simple calculation. The catch is that it's usually huge because the resolution is so high, which makes it almost unrealistic for storage or transmission ๐ญ.
So facsimile image data should be compressed to reduce its redundancy, so storage and transmission can be efficient ๐.
Run-length encoding is a useful compression scheme. Instead of storing the pattern, you store the counts of consecutive black and white runs to represent the image ๐.
Vector representation, where the run-lengths are coded as integers or bytes, is a useful internal representation of images ๐ฆ. It's reasonably compressed and also quite easy to process. Chopping, scaling and mask-scanning are examples of the processing operations it supports. A conversion between different compression schemes may have to happen by decompressing the data into vector format first and then recompressing it. Retrieval gets easier with a line index, which gives the pointers to each line of the image ๐งญ.
A higher compression rate leads to more efficient transmission, but it comes at the expense of ease of processing ๐ฅฒ. One example is the Huffman Code used in the CCITT 1-dimensional compression scheme. The data can be compressed more efficiently, but it's rather difficult to manipulate directly.
Taking the correlation between adjacent lines into account, 2-dimensional compression can achieve an even higher compression rate ๐. CCITT 2-dimensional compression and the DACOM facsimile machine use this method.
It's desirable to integrate facsimile images with other data types, like text and geometric graphics, and the structure of those other types must then be incorporated into the system ๐ซถ. Right now only text structure is available, while the structure for geometric graphics is a topic for further study ๐ฎ.
The facsimile system supports the following data structures. Their descriptions, if any, are listed too, and you can find them in Appendix 3 (except for dacom(device)) ๐.
type structure compression description
bit-map bit-map - -
vector 1D run-length vector(fax)
dacom block 2D run-length dacom(device)
CCITT T4 1D run-length t4(fax)
2D run-length t4(fax)
text text - text(fax)
Vector format is widely used as an internal data structure for data transfer between task processes ๐. The set of interface routines has been extended with two subroutines, getl() and putl(), which read and write line vectors directly through the Clean and Simple interface ๐ง. You can find these in Appendix 3 (getl(fax) and putl(fax)).
To check the validity of a vector file, there's a check task process, check(), that works as a data sink in a command string. It can also dump the vector elements of specific lines ๐.
4.6 Data Conversion ๐
To convert one data structure into another, the system provides several conversion modules in two categories: task processes and subroutines ๐. The task processes are MOS processes that can only be used in the environment described in this note. The subroutines are written in C and are compatible under UNIX, so they're more generally usable.
Character strings or text can be converted into vector format, so you can form an integrated image that combines picture and text ๐๐ผ๏ธ.
The following table lists these conversion modules, including their functions and descriptions (which can be found in Appendix 3) ๐๏ธ.
module type from to description
decomp process dacom vector decomp(fax)
recomp process vector dacom recomp(fax)
ccitt process vector t4 ccitt(fax)
t4 vector
bitmap subroutine vector bitmap bit-map(fax)
tovec subroutine bitmap vector tovec(fax)
ts subroutine ASCII string vector ts(fax)
string process ASCII string vector string(fax)
tf process text vector tf(fax)
Each DACOM block contains a Cyclic Redundancy Check (CRC) field, so the system supplies a subroutine, crc(), to calculate or check the CRC code ๐ (see crc(fax)).
If a vector file is to be printed on the DACOM facsimile machine, the image data should be re-compressed into the DACOM-block format first. The command string looks like this ๐จ๏ธ:
fs"e,pic|recomp|fax"w
where fs - file system task
e - read an existing file
ic - file name
recomp - re-compression task
fax - interface task for facsimile machine
w - print an image on facsimile machine
4.7 Image Manipulation ๐จ
Four processing task processes are provided in the system:
- Chop, which applies a defined window to the input image โ๏ธ.
- Scale, which enlarges or shrinks the input image to the defined dimensions ๐.
- Merge, which puts the input image on the specified area of a background image ๐งฉ.
- Clean, which removes the noise on the input image ๐งผ.
The Clean and Simple interfaces are supported in these processing tasks, so the tasks can be used in command strings. However, these tasks can be neither source nor sink in a command string ๐ . The data format of their input and output is vector.
For example, a facsimile page can be cleaned and then printed on the facsimile machine ๐จ๏ธโจ. Note that the image data must be recompressed before being sent to the facsimile machine. If the original data is in DACOM block form, it has to be decompressed first, because the processing tasks only accept line vectors. The command string is shown below.
fs"e,page|clean|recomp|fax"w
where fs - file system task
e - read an existing file
page - file name
clean - cleaning task
recomp - re-compression task
fax - interface task for facsimile machine
w - print an image on facsimile machine
The descriptions of these processing tasks can be found in Appendix 2 (chop(fax), scale(fax), merge(fax), and clean(fax)) ๐.
In the tasks chop and merge, a window is set by giving the coordinates of its vertices. But it's usually rather difficult for a human user to decide the exact coordinates ๐ต. So the system supplies a subroutine, choice(), which specifies a rectangular subsection of an image through interactive manipulation of a rectangular subsection on the screen of the Grinnell display showing the image ๐ฑ๏ธ. It provides a set of interactive commands so a user can intuitively choose the area they're interested in. Note that this subroutine must be called by a MOS process, and the Grinnell display must be included in the system.
By means of these image processing modules, the image editing described in section 2.4 can be carried out ๐ช. Let's look at an example. An image abstracted from a picture 'a' is to be merged onto a specified area of another picture 'b'. First, the two pictures 'a' and 'b' should be displayed on the left half and right half of the screen, respectively. Assume both are standard DACOM pages with dimensions 1726x1200. They have to be shrunk to fit the dimensions of the half screen (256x512). If the data format is not vector, conversion should be carried out first. The required command strings are:
e,a|scale"1726,1200,256,512|grinnell"0,511,255,0,z,g
fs"e,b|scale"1726,1200,256,512|grinnell"256,511,511,0,z,b
where fs - file system task
e - read an existing file
a - file name
b - file name
scale - scale task
1726,1200 - old dimension
256,512 - new dimension
grinnell - grinnell display interface task
0,511,255,0 - presentation area (the left half)
256,511,511,0 - presentation area (the right half)
z - zero write mode
g - green
b - blue
In an application process, the subroutine choice() is called in the following ways for the user to choose the areas on both pictures ๐
choice(r, 1726, 1200, 1, 0, 0);
/* choice the area on 'a' */
/* r - red
1726 - width of the original picture
1200 - height of the original picture
1 - left half of the screen
0 - the subsection can be of any width
0 - the subsection can be of any height
*/
choice(r, 1726, 1200, 2, 0, 0);
/* choice the area on 'b' */
/* r - red
1726 - width of the original picture
1200 - height of the original picture
2 - right half of the screen
0 - the subsection can be of any width
0 - the subsection can be of any height
*/
okay so here we go ๐ when the user finishes editing, the coordinates of the chosen rectangles get handed back to us โจ the table below shows an example. the widths and heights in it are worked out from those coordinates, and they tell us the source image has to be enlarged to fit its destination ๐
(0, 0)
+-------------------------------> x
|
| (x0, y0) w
| +--------------------+
| ! !
| ! !
| ! ! h
| ! !
| ! !
| +--------------------+
| (x1, y1)
V
y
original x0 y0 x1 y1 w h
a 30 40 100 120 70 80
b 100 100 1100 1100 1000 1000
at this point we can finally get our goal done ๐ by running the job below. the result image is going to be saved as a brand new file called 'c' ๐ฅน
fs"e,a|chop"30,40,100,120|scale"70,80,1000,1000
|merge"b,0,100,100,1100,1100|fs"c,c
where fs - file system task
e - read an existing file
a - file name
chop - chop task
30,40,100,120 - the area to be abstracted
scale - scale task
70,80 - old dimension
1000,1000 - new dimension
merge - merge task
b - file name of the background image
0 - to be overlaid
100,100,1100,1100 - the area to be overlaid
fs - file system task
c - create a new file
c - the name of the file to be
created
4.8 Data Transmission โจ
okay this part is the networking glow-up ๐ฆ to send facsimile image data over computer networks (using the setup in Fig. 1), the Network Independent File Transfer Protocol [9] gets built as a MOS task process. it supports the Clean and Simple interface from section 3.3 [10], which means this module can be used directly inside a command string ๐ it always runs in initiator mode, but server mode is supported too. you can read all about it in Appendix 2 (ftp(fax)) ๐
since it's network-independent, it uses a transport service to talk across the networks ๐ and the Clean and Simple interface is also what handles the chat between the module and the transport service processes ๐ซถ
so picture this ๐ผ๏ธ an image file lives in a remote file system and needs to get printed on your local facsimile machine. the data travels over the ARPANET [21], with Transport Control Protocol (TCP) [28] as the underlying transport service. like we said before, the network delay can cause a time-out on the local facsimile machine ๐ญ so the job has to be split into two subjobs.
- Subjob (1): fetch the remote file. the remote file gets sent over with the NIFTP module. the twist is that instead of going straight to the facsimile machine, the received data gets stored in a temporary file ๐ง
ftp"r,b,ucl,fax,pic;tcp:1234,10,3,3,42,4521|fs"c,tmp
where ftp - NIFTP task
t - receive
b - binary
ucl - remote user name
fax - remote password
pic - remote file name
tcp - transport service process
parameters for the transport service:
1234 - local channel number
10,3,3,42 - remote address
4521 - channel reserved for the
remote server
fs - local file system task
c - create a new file
tmp - the name of the file to be created
- Subjob (2): print it. the temporary file gets read, and the image is sent to the facsimile machine for printing. here it's assumed the data is already in DACOM block form, so no conversion is needed ๐
fs"e,tmp|fax"w
where fs - file system task
e - read an existing file
tmp - file name
fax - interface task for facsimile machine
w - print an image on facsimile machine
ok now the exciting bit ๐ we can swap image data with ISI and COMSAT! ๐ฅณ DACOM block is the only format that works right now, because all three participants have DACOM facsimile machines and no other data format is available at both ISI and COMSAT ๐ but the ARPA-Facsimile community plans to adopt the CCITT standard for future work โจ and as mentioned earlier, UCL already has this facility ๐
above NIFTP, there's a simple protocol that controls the transmission of facsimile data ๐ in it, a facsimile data file is defined like this: every DACOM block gets a 2-byte header at the front. that header has a length-byte (the length of the block, header included) and a code-byte (the type of the block) ๐ง here's the diagram:
|<--- header ---->|<------ 74 bytes ------->|
+--------+--------+-------------------------+
! length ! code ! DACOM block !
+--------+--------+-------------------------+
the length-byte is 76 (decimal) for all DACOM blocks ๐ข the code-byte is 071 (octal) for a setup block and 072 for a data block ๐ธ there's also a special EOP block that marks the end of a page ๐ it's just the header, with the length-byte set to 2, and its code-byte is undefined. a facsimile data file can hold several pages, and they're separated by EOP blocks ๐
5. CONCLUSION ๐
5.1 Summary
okay bestie, the history is iconic ๐ฐ๏ธ facsimile transmission techniques were invented back in 1843, but it wasn't until recent years that integrating with computer communication systems gave rise to "great expectation" ๐ญ this system captures the compatibility and flexibility of computerised facsimile systems ๐
in this system, facsimile no longer just means the transmission device. it means the function of moving hard copy from one place to another ๐จ the system doesn't just allow more reliable and accurate document transmission over computer networks, it also lets images be manipulated electronically ๐ผ๏ธ an image can be converted from one representation format to another, so different makes of facsimile machines can talk to each other ๐ซถ a picture can even be shown on different bit-map devices, like a TV-like screen, because it can be scaled to get around the incompatibilities ๐บ and the system provides windowing and overlaying facilities, which means a sophisticated editor can be supported ๐
one of the most important parts of this system is that text can be converted into its bit-mapped representation and integrated with pictures ๐คฏ geometric graphics could be included too. so the facsimile machine could act as a printer for multi-type documents ๐จ๏ธ it's clear that facsimile will play an important role in future information processing systems ๐ฆ
as far as the system itself goes, here are the advantages we can recognise โจ even though we focused on the facsimile system, lots of these features apply just as well to other information-processing systems ๐
- Flexibility: user jobs can be organised easily. all you have to do is make the logical links for the appropriate task processes ๐งฉ
- Simplicity: the interface routines take care of things like signal handling and buffer management. by avoiding that burden, the task processes become very "clean and simple" ๐งผ
- Portability: the interface routines also make the task processes totally independent of the operating environment. only these routines need to be modified if the environment changes ๐
- Ease of extension: the power of the system can be simply and infinitely extended by adding new task processes โญ
- Distributed Environment: this approach can easily be extended to a distributed environment, where limitless hardware and software resources can be provided ๐
5.2 Problems
ngl, this part is a bit of a letdown ๐ญ the network we used for the experiments was not designed for image data transmission. the data transfer is so slow that a time-out may happen on the facsimile machine ๐ local buffering solved this, and pictures were successfully exchanged over the network, but the slowness is still rather disappointing given how much image data there is ๐ the measurement showed the throughput was around 500 bits/sec. in other words, it took at least 5 minutes to transfer a page ๐ this was caused by the network, not our system ๐ซ the situation has improved recently. however, more efficient compression schemes are still required ๐ฅบ
at present, the system must be directly attached to the network to be accessed ๐ the network ports are in high demand, though, so frequent reconfiguration is needed ๐ ugh, a real main character problem ๐
The facsimile system can ONLY hang out on the local network, the Cambridge Ring ๐, and any foreign networks have to reach it through gateways that plug into the ring ๐ธ. This is shown in Fig. 12 โจ. The X25 network connects through an X25 gateway, XG [25], and SATNET connects through another gateway, SG [25]. Both networks work at the transport level, and XG and SG support the relevant transport procedures ๐ . For XG that means NITS/X25 ([26], [27]). For SATNET it means TCP/IP ([28], [29]) ๐ซถ.
UCL facsimile
system - - - - - - - -
+--------+ / \ +------+
! ! ---- Cambridge Ring ---- ! PE !
+--------+ \ / +------+
- - - - - - - - |
/ \ |
+------+ +------+ |
! XG ! ! SG ! --- SATNET
+------+ +------+
/ \
PSS SERC NET
Fig. 12 Schematic of UCL network connection
Okay so when the network software and the application software live on the same machine, the Clean and Simple interface from Section 3.5 is what the modules use to talk to each other ๐. When the gateway software got moved onto its own separate machine, an Inter-Processor Clean and Simple [30] was needed ๐ฆ. The right transport process gets handed over to the relevant gateway, and the right facilities get set up for addressing that gateway ๐. Otherwise the software doesn't need much changing to handle the distributed case โจ.
In our experimental work we ran into these problems too ๐ญ:
- The primary memory of the LSI-11 is so small that we cannot build a system with all the modules we've developed ๐. To transfer an edited picture using the NIFTP module, we first have to load an editor system to input and process the picture, and only then load the NIFTP system to transmit it ๐.
- Image processing procedures run super slowly ๐ข. For example, shrinking a picture to fit the screen of the Grinnell display takes several minutes ๐ฉ. This stops the system from being widely used in its present form ๐ซ.
- Floppy disks are far from adequate as secondary storage for image data files ๐พ. We have two double-density floppy disk drives, and each disk holds about 630K bytes. But an image page contains at least 50K bytes, and sometimes that number can double for a really complex picture ๐. So only a limited number of pages can be stored ๐.
On the other hand, our department has two PDP11-44s running UNIX, plus big disks giving us tons of file storage ๐. Their processing speed is much higher than the LSIs' ๐. The UNIX file system gives us a super convenient information-management environment ๐ , and that gave us the idea that UNIX could pretend to be a file server in charge of storing and managing the image data ๐ง. Then all the processing tasks could run on UNIX โจ. This doesn't just fix the problems above, it also brings these extra perks ๐:
- UNIX gives us a way better software-development environment than LSI MOS ever can or will ๐ .
- The facsimile service can be enhanced to support many users at a time ๐ซถ.
- The UNIX file system is so sophisticated that it can handle more complex data entities ๐ง .
The 44s and the LSI-11 (which the facsimile machine and Grinnell display are attached to) are all connected to the UCL Cambridge Ring ๐. That means you can build a distributed processing environment where a job on one computer can be kicked off by another, and then the job gets carried out by both computers working together ๐ค.
In that distributed setup, the LSI-11 microcomputer plus the facsimile machine basically become a totally passive facsimile server ๐ฆ, controlled by a UNIX user ๐. A page gets read on the facsimile machine, and the image data stream it produces is sent to UNIX over the ring ๐จ. The image data gets stored as a UNIX file and can be processed if needed ๐. It can also be sent over the ring back to the facsimile server, where it gets reprinted on the facsimile machine ๐จ๏ธ.
IPCS [30] is far from adequate for building this kind of distributed environment ๐ค, because it doesn't give you any facility for organising a remote job. In our system, the task controller was modified so that command strings can be supplied from a remote host on the network ๐. Once it accepts the request, the task controller organises the relevant task chain, and the requested job runs under its control ๐. Running a distributed job may require synchronisation between the two computers โฑ๏ธ. These problems are discussed in detail in [31] ๐.
Generally speaking, a distributed system built on a local network that supplies cheap, fast, and reliable communication could be the ultimate solution to the operational problems in this section ๐. In a system like that, different system operations get carried out in the most suitable places ๐.
For now, this system only has a procedure-oriented task-control language ๐. The command string of the fitter can be typed from the system console directly, and the matching job gets organised and executed โจ๏ธ. In theory, that's enough to cope with any requirement a user has ๐ค. But when a job gets complex, typing commands becomes super tedious and prone to error ๐ตโ๐ซ.
Above the task controller, a job-controller layer is required ๐ง. It provides a problem-oriented language so the user can easily put their requirement to the system ๐ฃ๏ธ. When a command comes in, the job controller translates it into a command string for the task controller and passes that string along so the operation request gets done ๐. Sometimes one job has to be divided into several subjobs, which get dealt with separately ๐งฉ. The job controller should also be responsible for high-level calculation and management, so the user doesn't need to care about system details ๐ .
In the system that supports facsimile service under UNIX, a set of high-level commands is provided ๐. The command strings for the facsimile station get arranged automatically, and they're totally hidden from the UNIX user ๐.
5.3 Future Study ๐ฎ
At the next stage, our attention should move to a higher-level, more sophisticated system that supports a multi-type environment ๐. In a system like that, the facsimile machine wouldn't just work as a facsimile input/output device. It should also play the role of a printer for multi-type documents ๐จ๏ธ. That's because other data types, e.g. coded character text and geometric graphics, can be easily converted into bit-mapped graphics format, which the facsimile machine is able to accept ๐.
First of all, a data structure should be designed to represent multi-type information ๐งฑ. In a distributed environment, that structure should be understood all over the system, so multimedia messages can be exchanged ๐.
In a future system, different services should be supported, including viewdata, Teletex, facsimile, graphics, slow-scan TV, and speech ๐. The techniques developed for facsimile will be generalised for use with other bit-mapped image representations, such as slow-scan TV ๐ฆ.
To improve the performance of the facsimile system, we are investigating how to use an auxiliary special-purpose processor to perform some of the image processing operations โก. Such a processor will be essential for the higher data rate involved in slow-scan TV ๐ฅ.
Reference ๐
- [1] P. T. Kirstein, "The Role of Facsimile in Business Communication", INDRA Note 1047, Jan. 1981.
- [2] T. Chang, "A Proposed Configuration of the Facsimile station", INDRA Note 922, May, 1980.
- [3] T. Chang, "Data Structure and Procedures for Facsimile Signal Processing", INDRA Note 923, May, 1980.
- [4] S. Treadwell, "On Distorting Facsimile Image", INDRA Note No 762, June, 1979.
- [5] M. G. B. Ismail and R. J. Clarke, "A New Pre-Processing Techniques for Digital Facsimile Transmission", Dept. of Electronic Engineering, University of Technology, Loughborough.
- [6] T. Chang, "Mask Scanning Algorithm and Its Application", INDRA Note 924, June, 1980.
- [7] M. Kunt and O. Johnsen, "Block Coding of Graphics: A Tutorial Review", Proceedings of the IEEE, special issue on digital encoding of graphics, Vol. 68, No 7, July, 1980.
- [8] T. Chang, "Facsimile Data Compression by Predictive Encoding", INDRA Note No 978, May. 1980.
- [9] High Level Protocol Group, "A Network Independent File Transfer Protocol", HLP/CP(78)1, alos INWG Protocol Note 86, Dec. 1978.
- [10] T. Chang, "The Implementation of NIFTP on LSI-11", INDRA Note 1056, Mar. 1981.
- [11] T. Chang, "The Design and Implementation of a Computerised Facsimile System", INDRA Note No. 1184, Apr. 1981.
- [12] T. Chang, "The Facsimile Editor", INDRA Note 1085, Apr. 1981.
- [13] K. Jackson, "Facsimile Compression", Project Report, Dept. of Computer Science, UCL, June, 1981.
- [14] R. Cole and S. Treadwell, "MOS User Guide", INDRA Note 1042, Jan. 1981.
- [15] CCITT, "Recommendation T.4, Standardisation of Group 3 Facsimile Apparatus for Document Transmission", Geneva, 1980.
- [16] "DACOM 6450 Computerfax Transceiver Operator Instructions", DACOM, Mar. 1977.
- [17] "AED 6200LP Floppy Disk Storage System", Technical Manual, 105499-01A, Advanced Electronics Design, Inc. Feb. 1977.
- [18] "The User Manual for Grinnelll Colour Display".
- [19] D. R. Weber, "An Adaptive Run Length Encoding Algorithm", ICC-75.
- [20] R. Braden and P. L. Higginson, "Clean and Simple Interface under MOS", INDRA Note No. 1054, Feb. 1981.
- [21] L. G. Roberts et al, "The ARPA Computer Network", Computer Communication Networks, Prentice Hall, Englewood, pp485-500, 1973. ๐
- [22] I. M. Jacobs et al: "General Purpose Satellite Network", Proc. IEEE, Vol. 66, No. 11, pp1448-1467, 1978. ๐ฐ๏ธ
- [23] J. W. Burren et al, "Design fo an SRC/NERC Computer Network", RL 77-0371A, Rutherford Laboratory, 1977. ๐ง
- [24] P. T. F. Kelly, "Non-Voice Network Services - Future Plans", Proc. Conf. Business Telecommunications, Online, pp62-82, 1980. ๐ผ
- [25] P. T. Kirstein, "UK-US Collaborative Computing", INDRA Note No. 972, Aug. 1980. ๐ค
- [26] "A Network Independent Transport Service", PSS User Forum, Study Group 3, British Telecom, London, 1980. ๐ก
- [27] CCITT, Recommendation X3, X25, X28 and X29 on Packet Switched Data Services", Geneva 1978. ๐ธ
- [28] "DoD Standard Transmission Control Protocol", RFC761, Information Sciences Inst., Marina del Rey, 1979. ๐
- [29] "DoD Standard Internet Protocol", RFC760, Information Sciences Inst., Marina del Rey, 1979. โจ
- [30] P. L. Higginson, "The Orgainisation of the Current IPCS System", INDRA Note No. 1163, Oct. 1981. ๐
- [31] T. Chang, "Distributed Processing for LSIs under MOS", INDRA Note No. 1199, Jan. 1982. ๐ฆ
Appendix I: Devices โจ
NAME
aed62 - double density floppy disk ๐พ
SYNOPSIS
DCT aed62
setdct("aed62", 0170, 0170450, 0170450,
aedini, aedsio, aedint, 0);
DESCRIPTION
okay so the Double Density disks have 77 tracks, numbered 0 to 76 ๐ง. Each track has 16 sectors (sometimes called blocks), which makes 1232 sectors on each side of the disk, numbered 0 to 1231. Each sector holds 512 bytes, so that's 630,784 bytes on each side of the floppy. Literally a whole lotta data, bestie ๐
Only one side can be accessed at a time ๐. There is only one head per drive, and it sits on the underside of the disk. To reach the other side, you have to manually take the disk out and put it back in the other way up. Main character struggle, ngl ๐ญ
Each block is actually two blocks on the disk: an address ID block and a data block ๐ฆ. The address ID block is used by the hardware and holds the track number, the block number, and the size of the data block that follows. When an operation is happening, the seek mechanism first finds the block by reading the address ID blocks and literally "hunting" for the right one. It will hunt for up to 2 seconds before reporting a failure โณ.
Both the address ID and the data blocks are followed by a checksum word. The hardware maintains it, and it's hidden from the user ๐ซฃ. When writing, the checksum is calculated and appended to the block. When reading, it's verified (for both the ID and data blocks), and any error is reported as a Data Check. On a write, nothing checks the data block, and the hardware has no idea if it was written correctly. The only way to verify it is to read it ๐.
There are two drives in the unit, but they cannot be used simultaneously ๐ซ. If an operation is in progress on one drive, no access can be made to the other until the first operation is complete. The driver will queue requests for both drives, though, and make sure they are performed in order ๐ซถ.
The MOS driver is called aed62.obj, and it operates on the following IORB entries ๐ง.
irfnc
The operation to be performed, as follows:
0 - Read
1 - Write
2 - Verify
3 - Seek
Read and Write cause data to be transferred to and from disk. Verify does a hardware read without transferring the data to memory, and it's used for verifying that the data can be successfully read. The checksum at the end of the block of each sector is verified by the hardware. The seek command is used to move the disk heads to a specified track. ๐ฏ
irusr1
The drive number. Only Zero or One is accepted. This is matched against the number dialed on the drive. If the number is specified on both drives, or neither, a hardware error will be reported. ๐ฅ
irusr2
The Sector or Block Number. Must be in the range 0 to 1231 inclusive. irusr2 specifies the block number that the transfer is to begin at for Read and Write, the beginning of the verified area for the Verify command, and the position of the head for the Seek command. In the latter case, the head will be positioned to the track that contains the block. ๐
iruva
This specifies the data address, which must be even (word boundary). If an odd address is given, the low order bit is set to zero to make it even. Not required for the Seek or Verify commands. ๐
irbr
Transfer length as a positive number of bytes. Not required for the seek command, but it IS used by the Verify command so that the correct number of blocks may be verified. The disk is only capable of transferring an even number of bytes. If an odd length is given, the low order bit is made zero to reduce the length to the lower even value. The length is NOT restricted to the sector size of 512 bytes. If the length is greater than 512, successive blocks are read or written until the required transfer length has been satisfied. If the length is not an exact multiple of 512 bytes, only the specified length will be read or written. Note that the hardware always reads and writes a complete sector, so specifying a shorter length on a read will cause the remainder of the block to be skipped. On a write, the hardware will repeat the last specified word until the sector is full. ๐ง
The driver will attempt to recover from all soft errors. There is no automatic write or read verify like on mag tapes, so data that is incorrectly written will not be detected as such until a read is attempted. For this reason, the verify feature can be used (see above) to force the checking of written data ๐. When an error is detected while performing a read, the offending block will be re-read up to 16 times, and disk resets will be attempted during this time too. If all of that fails, a hardware error indication is returned to the user. Other errors that are possible are Protection Error (attempt to write to a read-only disk) and User Error, which indicates that the parameters in the IORB were incorrect. Errors such as there being no disk loaded, or the drive door being open, are NOT detectable by the program. The interface sees these as Seek Errors (i.e. soft errors), so the driver will retry several times before returning a Hardware Error indication to the user. It should be noted that error recovery can take a long time. As mentioned above, there is a 2 second delay before a seek error is reported by the hardware, for instance โณ๐.
NAME
grinnell - colour display ๐ท
SYNOPSIS
DCT grndout
setdct("grndout", 03000, 0172520, 0172522,
grnoi, grnot, grnoti, &grndin);
DCT grndin
setdct("grndin", 03000, 0172524, 0172526,
grnoi, grnot, grnoti, &grndout);
DESCRIPTION โจ
okay so the Grinnell colour display is giving 512x512 pels ๐ That's the whole screen. You get three colours to play with (red, green and blue), but there's no grey scale, so no moody black-and-white looks ๐ It has three graphics modes:
- Alphanumeric: the input ASCII characters get displayed at the selected positions on the screen ๐
- Graphic: basic geometric elements, like lines and rectangles, get drawn with graphics commands โ๏ธ
- Image: the input data gets read as bit patterns, and the matching images get illustrated ๐ผ๏ธ
The values used to build commands are explained in the Grinnell User Manual ๐ but I've also listed them below so you don't have to go digging ๐ซถ
#define LDC 0100000 /* Load Display Channels */
#define LSM 0010000 /* Load Subchannel Mask */
#define RED 0000010 /* Read Subchannel */
#define GREEN 0000020 /* Green subchannel */
#define BLUE 0000040 /* Blue subchannel */
#define WID 0000000 /* Write Image Data */
#define WGD 0020000 /* Write Graphic Data */
#define WAC 0022000 /* Write AlphanumCh */
#define LWM 0024000 /* Load Write Mode */
#define REVERSE 0200 /* Reverse Background */
#define ADDITIVE 0100 /* Additive (not Replace) */
#define ZEROWRITE 040 /* Dark Write */
#define VECTOR 020 /* Select Vector Graph */
#define DBLEHITE 010 /* Double Height write */
#define DBLEWIDTH 004 /* Double Width write */
#define CURSORAB 002 /* Cursor (La+Lb,Ea+Eb) */
#define CURSORON 001 /* Cursor On */
#define LUM 0026000 /* Load Update Mode */
#define Ec 001 /* Load Ea with Ec */
#define Ea_Eb 002 /* Load Ea with Ea + Eb */
#define Ea_Ec 003 /* load Ea with Ea + Ec */
#define Lc 004 /* Load La with Lc */
#define La_Lb 010 /* Load La with La + Lb */
#define La_Lc 014 /* Load La with La + Lc */
#define SRCL_HOME 020 /* Scroll dsiplay to HOME */
#define SRCL_DOWN 040 /* Scroll down one line */
#define SCRL_UP 060 /* Scroll up one line */
#define ERS 0030000 /* Erase */
#define ERL 0032000 /* Erase Line */
#define SLU 0034000 /* Special Location Update */
#define SCRL_ZAP 0100 /* unlimited scroll speed */
#define EGW 0036000 /* Execute Graphic Write */
#define LER 0040000 /* Load Ea relative */
#define LEA 0044000 /* Load Ea */
#define LEB 0050000 /* Load Eb */
#define LEC 0054000 /* Load Ec */
#define LLR 0060000 /* Load La Relative */
#define LLA 0064000 /* Load La */
#define LLB 0070000 /* Load Lb */
#define LLC 0074000 /* Load Lc */
#define LGW 02000 /* perform write */
#define NOP 0110000 /* No-Operation */
#define SPD 0120000 /* Select Special Device */
#define LPA 0130000 /* Load Peripheral Address */
#define LPR 0140000 /* Load Peripheral Register */
#define LPD 0150000 /* Load Peripheral Data */
#define RPD 0160000 /* ReadBack Peripheral Data */
#define MEMRB 00400 /* SPD - Memory Read-Back */
#define DATA 01000 /* SPD - Byte Unpacking */
#define ALPHA 06000 /* LPR - Alphanumeric data */
#define GRAPH 04000 /* LPR - Graphic data */
#define IMAGE 02000 /* LPR - Image data */
#define LTHENH 01000 /* take lo byte then hi byte */
#define DROPBYTE 0400 /* drop last byte */
#define INTERR 02000 /* SPD - Interrupt Enable */
#define TEST 04000 /* SPD - Diagnostic Test */
The MOS driver is called grin.obj. It operates on the following IORB entries.
iruva: This is a pointer to the buffer where the data is stored. This data must be ready formatted for the Grinnell, since no conversion is performed by the driver. ๐irbr: This is the transfer length, as a positive number of bytes. ๐ง
Addressing the Grinnell: rows consist of elements numbered 0 to 511, running left to right. The lines are numbered from 0 to 511, running from bottom to top. So it's addressed like a conventional X-Y coordinate system ๐ Note that this coordinate system is different from the one used for the image. ๐
X A
|
| (511, 511)
511 +-------------------------------+
| |
| |
| |
| |
| (x, y) |
| + |
| |
| |
| |
| |
| |
+-------------------------------+----->
0 511 Y
SEE ALSO
grinnell(fax)
NAME
dacom - facsimile machine ๐
SYNOPSIS
DCT faxinput
setdct("faxin", 0350, 0174750, 0174740,
faxii, faxin, faxini, &faxoutput);
DCT faxoutput
setdct("faxout", 0354, 0174752, 0174742,
faxoi, faxot, faxoti, &faxinput);
DESCRIPTION ๐
The DACOM facsimile machine can read a document and create the matching image data blocks. It can also accept data in the right format and print the matching image ๐จ๏ธ
Each data block is 585 bits, and it's stored in a block of 74 bytes that starts on a byte boundary. The final 7 bits of the last byte aren't used, and they're undefined ๐คทโโ๏ธ You need to read the 585 bits in each block as a bit stream: the bits in each byte run from the high-order end of the byte to the low-order end. The last 12 bits of the 585 bits in each block make up the CRC field, which is how the block can be validated โ
There are two kinds of blocks: SETUP blocks and DATA blocks. The first block of an image data file should be a single SETUP block. Every block after that in the file must be a DATA block. Also, the second block is a DATA block that holds ZERO samples, so it's a dummy data block ๐ From the third block onward, the DATA blocks store the real image data ๐ซถ
A standard DACOM page has about 1200 scan lines, and each line has 1726 pels. One can choose
Appendix II: Task Controller and Task Processes ๐ง
NAME
ccitt - conversion between vector and CCITT T4 format ๐ฆ
SYNOPSIS
ccitt() - a MOS task
command string (task name is defined as ccitt):
ccitt"<function>
DESCRIPTION ๐ธ
This routine runs as a MOS pipe task to convert vectors to CCITT T4 format, or the other way around ๐
The parameter function says what the task is supposed to do ๐
value function
1c one-dimensional compression
1d one-dimensional decompression
2c[<k>] two-dimensional compression
2d two-dimensional decompression
Note: k is the maximum number of lines to be coded two-dimensionally before a one-dimensionally coded line is inserted. If k is omitted, the default value 2 gets used โจ
SEE ALSO
vector(fax), t4(fax), fitter(fax)
NAME
check - check the validity of a vector file. ๐
SYNOPSIS
check() - a MOS task
command string (the task name is defined as check):
check"<function>,<width>,<height>,[<from>,<to>]
DESCRIPTION ๐
This routine runs as a MOS pipe task that checks the validity of the input vector file ๐ต๏ธโโ๏ธ
The number of lines to be checked is set by the parameter height. If the height of the image is less than the parameter, the actual height gets printed. So you can set height to a big number if you want to count the lines in the input image ๐งฎ
The run lengths in each of these lines are added up, and the sum gets compared with the parameter width ๐
These are the basic functions that run every time the task is invoked. But you can also pick from a few options by setting the one-character parameter function ๐
value function
'n' basic function only
'c' print the count of each line
'l' print all lines
's' print the lines in the interval
specified by parameter from and to
DIAGNOSTICS
A bad line gets reported, and it causes the job to be aborted. ๐
SEE ALSO
vector(fax), getl(fax), fitter(fax)
NAME
chop - extract a designated rectangular area from an image โ๏ธ
SYNOPSIS
chop() - a MOS task
command string (task name is defined as chop):
chop"<x0>,<y0>,<x1>,<y1>
DESCRIPTION ๐
This routine runs as a MOS pipe task that extracts a designated rectangular area from an input image. The input and output are both image data files in the form of vectors ๐ผ๏ธ
Here's the coordinate system being used ๐ Note that the lengths are measured in number of pels.
(0, 0) width X
+-------------------------+---->
| |
| |
| (x0, y0) |
| +---------+ |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| +---------+ |
| (x1, y1) |
| |
| |
| |
| |
height +-------------------------+
|
|
Y V
As you can see in the diagram, the rectangular area to be extracted is specified by the parameters x0, x1, y0 and y1, which are decimal strings ๐
BUGS
One has to make sure that ๐
0 < x0 < width
0 < y0 < height
0 < x1 < width
0 < y1 < height
SEE ALSO
vector(fax), getl(fax), putl(fax), fitter(fax)
NAME
clean - clean an image. ๐งฝ
SYNOPSIS
clean() - a MOS task
command string (task name is defined as clean):
clean"<width>,<height>
DESCRIPTION ๐
This routine runs as a MOS pipe task that cleans an image by means of mask scanning ๐ซง The input and output are both image data files in the form of vectors.
The width and height should be given as the parameters ๐
SEE ALSO
vector(fax), getl(fax), putl(fax), fitter(fax)
NAME
decomp - decompress DACOM blocks ๐ธ
SYNOPSIS
decomp() - a MOS task
command string (task name is defined as decomp):
decomp
DESCRIPTION โจ
This task takes DACOM blocks from the Clean and Simple interface and decompresses them into vector format ๐ Then it writes the vectors to the Clean and Simple interface ๐ซถ
SEE ALSO โจ
dacom(dev), vector(fax), fitter(fax)
FAX(FAX) FAX(FAX)
NAME ๐
fax - interface process for DACOM facsimile machine
SYNOPSIS ๐
fax() - a MOS task
command string (task name is defined as fax):
fax"<function>
DESCRIPTION ๐ฆ
okay so this task is the Clean and Simple interface ๐ and it's how you read or write facsimile image data. so cute, right? ๐ซถ
the one character function parameter decides which way the data goes. w is for writing, and in that case it expects 74 byte DACOM blocks with correct CRC fields already in them ๐. r is for reading, which means a document gets read on the facsimile machine and the DACOM blocks get created for you โจ it's giving "magic on paper" energy ๐ฅ
SEE ALSO ๐ธ
dacom(dev), fitter(fax)
FITTER(FAX) FITTER(FAX)
NAME ๐ง
fitter - fit processes together to form a data pipe
SYNOPSIS ๐
fitter() - the MOS task controller
DESCRIPTION ๐
bestie, this one is the main character of the whole pipeline ๐. based on the command string you type on the console, fitter links the named processes together into a task chain. the process names are the ones given in the PCB ๐. the processes have to talk to each other using the C+S interface, and only one C+S interface is opened per process. data gets pushed in with a cswrite and pulled back out with a csread ๐ฆ
the fitter never looks inside the data. it just passes it from one process to the next, no judging ๐ซถ
the format of the command string is:
A | B | C.
so here's the vibe. the fitter takes data from the process called A and writes it to the process called B. then it reads data from B and writes that to C. โจ the middle processes get both read and written, while the first one in the list only gets read from and the last one only gets written to ๐
you can also attach a double quote as the separator between the task name and its open parameter string, like this:
A"500 | B"n,xyz | C,
in that example, 500 and n,xyz are the open parameter strings for tasks A and B. ๐ the parameter string gets passed to the matching task routine when the csopen call returns. iykyk ๐
DIAGNOSTICS ๐
the command string containing an undefined task will be rejected. not me getting rejected for being undefined ๐ญ
SEE ALSO ๐
csinit(fax), csopen(fax), csread(fax), cswrite(fax)
FS(FAX) FS(FAX)
NAME ๐
fs - file system for use under MOS
SYNOPSIS ๐ท
fs() - a MOS task
command string (task name is defined as fs):
fs"<funciton>,<file_name>
DESCRIPTION ๐
this is a file system built on the Double Density floppy disk, made for use under MOS ๐พ. the fs task is how you manipulate the files that the file system manages โจ the catch is that this task can only sit at the first or last spot in a command string. if it's first, the specified file gets read. if it's last, the file gets written ๐ฆ
the <function> field holds just one character, and that character picks the function. the options are:
e - open an existing file (for reading).
c - open an existing file, and set the length
to zero (for rewriting).
a - append to an existing file.
and if you use the capitals A, C, or E, the functions work the same as above, except the specified file gets created if it doesn't exist ๐ new file, who dis ๐ซถ
BUGS ๐
okay, the tea: this task is for reading and writing only ๐ญ for everything else, like seek, delete, status and sync, you have to go straight to the C+S interface.
also, only 15 files are allowed per disk, only drive 0 is supported right now, and no hierarchical directories allowed. it's a lot, I know ๐
SEE ALSO ๐ง
aed62(dev), fitter(fax)
NAME ๐
ftp, pftp - NIFTP task processes
SYNOPSIS ๐
ftp(), pftp() - MOS tasks
command string (task name is defined as ftp):
ftp"<function>,<code>,<user_name>,<password>,<file_name>;
<trasport_service_process>:<transport_service_parameters>
DESCRIPTION ๐
these tasks are an implementation of the Network Independent File Transfer Protocol (NIFTP) for LSIs running under MOS ๐ฆ they use a transport service to talk to a remote host on the network, and the same protocol has to be supported over there too. they talk to the user process and the transport service processes through the Clean and Simple interface, so they can slot right into a fitter command chain โจ
there are two versions. ftp is a P+Q version that supports both server and initiator roles, and pftp is a P version that only works as an initiator. both of them can send and receive ๐ซถ
this NIFTP is just a subset of the protocol, because its main purpose is to give the facsimile system a data transmission mechanism ๐ for the sake of simplicity, only the necessary facilities made it into the module. stuff like data compression and error recovery is not implemented, so no cap, it's lean ๐
the table below shows the transfer control parameters being used:
Attribute Value Mod. Remarks
Mode of access 0001 EQ Creating a new file
8002 EQ Retrieving file
Codes - - Text file, any parity
1002 EQ Binary file
Format effector 0000 EQ No interpretation
Binary mapping 0008 EQ Default byte size
Max record size 00FC EQ Default record size
Transfer size 0400 LE Default transfer size
Facilities 0000 EQ Minimum service
here's what each parameter in the command string means ๐
function is the NIFTP function of our site. any ASCII string starting with t means the file is to be transmitted to the remote site. anything else means the file gets retrieved from the remote site ๐ค๐ฅ
code tells you the type of file being transferred. any ASCII string starting with b means it's a binary file, and everything else means text file ๐ธ
user_name is the login name of the server site ๐ง
password is the password of the server site. shh, don't share it ๐
file_name is the name of the file to be transmitted ๐
transport_service_process is the process name of the transport service you want to use ๐
transport_service_parameters is the parameter string that the transport service needs. they're network dependent, and the corresponding transport service decides what they look like ๐
SEE ALSO ๐ฆ
fitter(fax)
NAME โจ
grinnell - task to convert and display fax vector data
SYNOPSIS ๐
grinnell() - a MOS task
command string (task name is defined as string):
grinnell"<x0>,<y0>,<x1>,<y1>,<mode>,<colour>
DESCRIPTION ๐ฅ
this task takes vector data from a Clean and Simple interface and displays it on the Grinnell screen ๐ฅ๏ธ picture the screen as an X-Y plane, with (0,0) at the lower left hand corner, (512, 0) at the lower right hand corner, and so on ๐
the x0, y0, x1, and y1 parameters are decimal strings. they define the rectangular space on the screen where the image goes ๐ if the image is smaller than that area, it gets artificially expanded to fill it. if the image is bigger, it gets truncated to fit the area โ๏ธ
the colour field is any combination of r, g, or b, which stand for red, green, and blue ๐ so for example, "gb" writes the image as yellow ๐ the colour mixing is giving art class ๐จ
the mode decides how the image gets displayed. any combination of r, a, and z works:
r = reverse image
a = additive image
z = zerowrite image.
okay the bit plane stuff is a little deep, so bear with me ๐ซถ there are three bit planes, one for each colour. normally, the bit planes for the selected colours get either zero bits or one bits written to them, depending on whether the image or the background is being written.
zerowrite means every non-selected bit plane (aka every colour you didn't pick) is always set to zero, so it erases any unselected colours in that area ๐งน
additive mode means the new bits get ORed into the selected colour planes instead of just being written. so the image gets added to, not replaced ๐
reverse mode flips things. bits that would be written as one bits get written as zero bits, and the bits that would be written as zero bits get written as one bits. in other words, the bits get flipped before they're used ๐ plot twist ๐
SEE ALSO ๐ง
grinnell(dev), vector(fax), fitter(fax)
NAME ๐ธ
merge - merge two images together
SYNOPSIS ๐
merge() - a MOS task
command string (task name is defined as merge):
merge"<file_name>,<action>,<x0>,<y0>,<x1>,<y1>
DESCRIPTION ๐
this routine works as a MOS pipe task that merges two images together to make the result image โจ the input and output are both image data files in the form of vectors ๐ฆ
one of the two input images is called the background, and it gets copied directly. you point to it with the file_name parameter ๐ the background's image data is read through a 'tunnel' that this task maintains. the other input image comes from the Clean and Simple interface managed by the fitter ๐ซถ
the position where that second image goes on the background is set by x0, y0, x1, and y1, which are decimal strings. see the diagram below ๐
(0, 0) width X
+-------------------------+---->
| |
| (x0, y0) |
| +---------+ |
| | | |
| | | |
| | | |
| | | |
| | | |
| +---------+ |
| (x1, y1) |
| |
| |
| (back ground) |
height +-------------------------+
|
|
Y V
that means the dimension of the image works out to x1 - x0 by y1 - y0 ๐
the action parameter decides how the two images get merged ๐ if it's set to 0, the second image is simply overlaid on the background. any non-zero value makes the second image replace the specified area of the background instead ๐
BUGS ๐
one has to make sure that
0 < x0 < width_of_back_ground
0 < y0 < height_of_back_ground
0 < x1 < width_of_back_ground
0 < y1 < height_of_back_ground
in addition, x0, y0, x1, and y1 must be consistent with the dimension of the image. no vibes-only coordinates allowed ๐
SEE ALSO ๐ง
vector(fax), getl(fax), putl(fax), chop(fax), fitter(fax)
OD(FAX) OD(FAX)
NAME ๐
od - dump the input data
SYNOPSIS ๐ท
od() - a MOS task
command string (task name is defined as od):
od"<format>
The original text in this part stops at the csread SYNOPSIS (int tid, need;), and there's no DESCRIPTION after it in what you sent. I don't want to invent the csread description, since implementers depend on every word, so I haven't written anything for this part.
Please paste the next chunk of the original, starting with csread's DESCRIPTION, and I'll pick up from there in the same style.
DESCRIPTION โจ
okay so this is the getl call ๐ it reads a line vector from the Clean and Simple interface, and the code is re-entrant, so only one copy is needed for all processes in a system. iconic ๐ซถ
the tid is the word you get back from csinit, so pass that in. the routine hands you a pointer to the buffer where the line vector is stored ๐ฆ
DIAGNOSTICS ๐
you get 0 back when end of file is reached. that's your signal, periodt ๐ธ
BUGS ๐
ngl this one's scary ๐ญ any memory violation aborts the whole task chain.
SEE ALSO ๐
vector(fax), putl(fax), fitter(fax)
PUTL(FAX) PUTL(FAX)
NAME ๐
putl - put a line vector onto the Clean and Simple Interface ๐
SYNOPSIS ๐ง
putl(tid, buf);
int tid, *buf;
DESCRIPTION ๐
this one is how you write a line vector to the Clean and Simple interface, and yes, it's re-entrant too, so one copy covers every process in the system โจ
tid is the word csinit gave you, and the line vector sits in the buffer that buf points at ๐
SEE ALSO ๐ธ
vector(fax), getl(fax), fitter(fax)
NAME ๐
t4 - the data format from CCITT recommendation T4 ๐ฆ
DESCRIPTION ๐
okay this is the big one, so get comfy bestie ๐๏ธ
Dimension and Resolution: vertically, the resolution is set like this:
Standard resolution: 3.85 line/mm
Optional higher resolution: 7.70 line/mm
horizontally, the standard resolution is 1728 black and white picture elements along the standard line length of 215 mm. you can also go with 2048 or 2432 picture elements along a scan line length of 255 or 303 mm, respectively. input documents up to a minimum of ISO A4 size should be accepted ๐ฅ
One-Dimensional Coding: this uses the popular modified Huffman coding scheme for run length compression. black and white runs get swapped out for base 64 code representations. it compresses well because code word lengths are inversely related to how likely a run is to show up ๐ง
there's a special code, EOL (End of Line), which is 000000000001, and it follows every line of data. it kicks off the facsimile message phase. the control phase comes back when you send six contiguous EOLs, which is the RTC ๐ญ
start of the facsimile data
|
v
+---+------+---+------+-/
!EOL! DATA !EOL! DATA !
+---+------+---+------+-/
end of the facsimile data
|
v
/-+---+------+---+---+---+---+---+---+
!EOL! DATA !EOL!EOL!EOL!EOL!EOL!EOL!
/-+---+------+---+---+---+---+---+---+
|<------ RTC ------->|
Two-Dimensional Coding: this one is called the Modified READ Code and it's giving main character energy ๐ it codes a line by referencing the line above it, so the correlation between adjacent lines makes compression way more efficient โจ
to keep the damage contained after transmission errors, a one-dimensionally coded line gets sent after one or more two-dimensionally coded lines. then the bit right after the EOL tells you which kind of coding the next line uses:
EOL1: one-dimensional coding;EOL0: two-dimensional coding.
start of the facsimile data
|
v
+----+--------+----+--------+-/
!EOL1!DATA(1D)!EOL0!DATA(2D)!
+----+--------+----+--------+-/
end of the facsimile data
|
v
/-+----+--------+----+----+----+----+----+----+
!EOL0!DATA(2D)!EOL1!EOL1!EOL1!EOL1!EOL1!EOL1!
/-+----+--------+----+----+----+----+----+----+
|<--------- RTC --------->|
TEXT(FAX) TEXT(FAX)
NAME ๐ธ
text - the text format for use in the facsimile system ๐
DESCRIPTION ๐ฆ
this is the representation structure for coded character text, used in the facsimile system โจ
it's a series of character strings, one per text line, and there are no control characters like <CR> and <LF> in the structure at all ๐ each text line starts with a count byte that tells you how many characters are on that line. the character string comes right after the count byte. a zero count means end of file ๐
EXAMPLES ๐
here's an example text:
This is a text.
This is a picture.
and here's how it gets represented:
<017> T h i s <040> i s <040> a <040> t e x t .
<022> T h i s <040> i s <040> a <040> p i c t u
r e . <0>
TS(FAX) TS(FAX)
NAME ๐ง
ts - translate an ASCII string into vector format ๐
SYNOPSIS ๐
ts(ar_in, left, right, tid)
char *ar_in;
int left, right, tid;
DESCRIPTION โจ
this routine takes a zero-ended ASCII string, pointed to by ar_in, and converts it into vector format ๐ฆ the font is a set of 12x20 matrices, so you get 20 line vectors out of it. those get written to the Clean and Simple interface by calling cswrite, and you have to pass in your task identifier tid ๐
you can pad blanks at the two ends of the text line using left and right. these are measured in pels, so keep that in mind ๐
the result should be an image whose dimension is:
width = left + 12*length + right;
height = 20;
where length is the number of characters in the input string ๐ธ
under the hood, the bitmap gets built first, and then it's converted into vector format by calling tovec ๐ฅ
BUGS ๐
the input string needs to end with a zero field ๐ญ
SEE ALSO ๐
vector(fax), tovec(fax), csinit(fax), cswrite(fax), fitter(fax)
VECTOR(FAX) VECTOR(FAX)
NAME ๐
vector - the internal data structure for a facsimile image ๐
DESCRIPTION ๐
this is the representation structure for binary images, and it uses a simple run length compression algorithm ๐ง most image files stay in vector format because it's way easier to process them that way โจ
the vector format is a series of integer vectors, one vector for each row of pels in the image. each vector gets a count word in front of it, which tells you how many integer words are in the vector ๐ฆ
after the count field, the first element is the number of white pels in the first run of the line. the second word gives the number of pels after that initial white run, and so on until the end of the vector. the first run length element has to refer to a white run, so if the first run is black, set it to 0 ๐
EXAMPLES ๐
a line consists of 20 pels like this:
00011111111011100000
and it can be represented as:
5, 3, 8, 1, 3, 5
the inverse of the line:
11100000000100011111
should be represented as:
6, 0, 3, 8, 1, 3, 5
๐ฆ where this page comes from
- ietf: rfc809 1982-02
- ๐ girlified by claude-haiku-5-5 on : a language model's rewrite of the original, under its terms