RFC 798

Decoding facsimile data from the Rapicom 450

πŸ“… published September 1981, from ietf

RFC 798: Decoding Facsimile Data from the Rapicom 450 πŸŽ€

okay bestie, let's get into it πŸ¦‹ this RFC is from September 1981, it's from the Network Working Group, and it's written by A. Katz of ISI (Information Sciences Institute). it's RFC 798 in the Request for Comments series. the header doesn't list a category, and it doesn't obsolete or update any other RFC. πŸ’…


I. Introduction ✨

okay so this note explains how to build a program that decodes facsimile data from the Rapicom 450 fax machine πŸ“  and turns it into an ordinary bitmap. once you have a bitmap, you can show it on other devices, edit it, and then encode it back into Rapicom 450 format. 🌸

to make this happen, you have to understand how the fax machine encodes and decodes its data, and then recreate that process in software. the algorithm is described in an article by Weber [1] and in a memo by Mills [2]. ngl, those papers don't include quite enough detail to actually decode the data successfully, so there's extra work to do. 😭

the program was written in L10 as a subsystem of NLS, running on TOPS20. the fax machine connects to TOPS20 as a terminal through a microprocessor-based interface called FAXIE. 🧚

big thank-you to Steve Treadwell of University College, London, and Jon Postel of Information Sciences Institute, who helped out. 🫢


II. Interface to TOPS20 πŸ’œ

the fax machine is hooked up to a microprocessor-based unit called FAXIE. it was designed and built by Steve Casner and Bob Parker. if you want the detailed info, check out reference [3]. πŸ”₯

FAXIE connects to TOPS20 over a terminal line. a program was written to read the data coming over that line and store it in a file. the decoding program then reads the fax data from that file. ✨

here's the bit-level chaos πŸ™ˆ the data comes out of the fax machine serially. FAXIE reads it into an 8-bit shift register and sends each 8-bit byte (octet) over the terminal line. the fax machine uses MARK for logical 0's and SPACE for logical 1's, which is backward from RS232, so FAXIE complements each bit in the octet. πŸ™ƒ

the data reaches TOPS20 as octets, most significant bit first. if you read each octet from most significant bit to least significant bit, in the order FAXIE sends it to TOPS20, you're reading the data in the same order it came into FAXIE from the fax machine. the vibes are immaculate πŸ‘‘

now the storage standard. the way Rapicom 450 facsimile data gets stored is described in RFC 769 [4]. according to that standard, each octet coming from FAXIE must be complemented and inverted (that means flipping the order of the bits in the octet). so the receiving program does that before it stores the data in a file. then, when the decoding program reads the file, it must invert and complement each octet before reading the data. it's giving double flip, but it's correct 🌈

each data block from the fax machine is 585 bits long. the end of the data gets padded with 7 0's, which makes it 592 bits, or 74 octets. πŸ“

per RFC 769, each block is stored in a file with a length octet and a command octet in front of it. there are three possible commands:

  • 56 (70 octal): a Set-Up block. this is the first block in the file, and it holds information about the fax image. πŸŽ€
  • 57 (71 octal): a data block. this covers the rest of the blocks in the file, except for the last one. πŸ’–
  • 58 (72 octal): an END command. this is the last block in the file. πŸ¦‹

the length field tells you how many octets are in the block. it's always 76 (114 octal), except for the END command, which can be 2 (no data). the length and command octets are NOT inverted and complemented. πŸ’€

here's a diagram of each block in the file:

+--------+--------+--------+--------+--------+--------+--------
| length | command|  data  |  data  |  ...   |        |
+--------+--------+--------+--------+--------+--------+--------

🌸 that's the whole layout, and it's iconic.

III. The Rapicom 450 Encoding Algorithm ✨

okay bestie, so an ordinary 8 1/2" by 11" document is made up of about 2100 scan lines, and each line has 1726 pels (picture elements) in it πŸ“„. Every pel is either black (1) or white (0) πŸ–€πŸ€

The Rapicom 450 has three picture quality modes πŸ’… In fine detail mode, the whole document gets encoded. In quality mode, only every other scan line is encoded, and the missing lines get filled in on playback by copying the previous line πŸͺ„ There's also express mode, where only every third line is encoded πŸƒβ€β™€οΈ

Data is encoded two lines at a time using a special two-dimensional run-length encoding scheme 🌈 There are 1726 pels on top and 1726 pels on the bottom. Each top-bottom pair of pels is called a column πŸ’œ For each of the 1726 columns, you can have any one of four configurations (called states):

          column
       (top-bottom)        pels         state
       ------------        ----         ------
           W-W             0,0            0
           W-B             0,1            1
           B-W             1,0            2
           B-B             1,1            3

The encoding algorithm can be described as a non-deterministic finite-state automaton, shown in Fig. 1 (after Mills [2]) 🧚 You start out in a state (0-3) and move to another state by emitting the right bits marked along the arcs of the diagram ✨ For example, say you're in state 1 (WB). To go to state 2 (BW), you'd output the bits 101 (binary). To go to state 0 (WW), you'd output the bits 1000. Note that the number of bits on each transition is variable πŸ¦‹

In states 0 (WW) and 3 (BB), a special run-length encoding scheme is used πŸŽ€ Each of these two states has two state variables. One is a run-length counter, and the other is the field length (in bits) of that counter. When you enter either of these states, the counter gets set to zero and goes up by one for every extra column of the same state πŸ”’ At the end of the run, the counter gets sent out, extended with high-order zeros if needed. If the count fills up the field, it gets sent, the field length goes up by one, and the count starts over again πŸ” This count is called the run length word, and it's between 2 and 7 bits long πŸ’–

Let's do an example, bestie πŸ‘€ Say we're in state 0 (WW) and the run length for this state (the white run length) is 3. If there are three 0's in a row, the first 0 was already encoded when we entered this state, so there are two more 0's that need encoding. That means we'd send 010 (binary). Similarly, if there are seven 0's in a row, we'd send 110. But eight 0's would be sent as 111 followed by 0000, and the white run length becomes 4 😭 (Ten 0's would be encoded as 111 followed by 0010, and the white run length would be 4 too.)

                              0100
        ------------------------>-----------------------------------
        |                                                          |
        |    -------------------<-------------------------------   |
        |   |                  1                               |   |
        |   V                                                  |   |
  ----------------                       -----------------     |   |
  |              |                       |               |     |   |
  |              |          010          |               |     |   |
|->|      2       |---------------------->|       1       |->|  |   |
|  |              |                       |               |  |  |   |
0|  |     B-W      |          101          |      W-B      |  |1 |   |
|<-|              |<----------------------|               |<-|  |   |
  |              |                       |               |     |   |
  |              |                 ----->|               |     |   |
  ----------------                 |     -----------------     |   |
      |   ^                        |      |     |   ^          |   |
      |   |     ------------>------|      |     |   |          |   |
      |   |     |           1             |     |   |          |   |
      |   |     |                         |     |   |          |   |
      |   |     |                         |     |   |          ^   V
      |   |     |                         |     |   |          |   |
  0111|   |1    |                         | 1000|   |1         |   |
      |   |     |                         |     |   |          |   |
      |   |     |                         |     |   |          |   |
      |   |     |                         |     |   |          |   |
      |   |     |            1011         |     |   |          |   |
      |   |     |    ----------<-----------     |   |          |   |
      V   |     |    |                          V   |          |   |
  ----------------   |                   -----------------     |   |
  |              |<---                   |               |     |   |
  |              |          0            |               |     |   |
  |      3       |<----------------------|       0       |------   |
  |              |                       |               |         |
  |     B-B      |                       |      W-W      |         |
  |              |---------------------->|               |<---------
  |              |          0            |               |
  |              |                       |               |
  ----------------                       -----------------
      |    ^                                   |    ^
      |    |                                   |    |
      ------                                   ------
       run                                      run
                           Figure 1.
 Non-deterministic finite-state machine diagram for RAPICOM 450

Run length word lengths must be between 2 and 7 🎯 The field length gets decremented if the run is encoded in one word and:

  1. If the run length is 3 and the highest order bit is 0.
  2. Or, if the run length is 4, 5, 6, or 7 and the highest order 2 bits are 0.

There's also a special rule that kicks in if the run takes up at least two run words (and might involve bumping up the run word size) and the run ends exactly at the end of a scan line πŸ™ˆ In that case, the last word of the run gets checked for decrement as if the previous words in the run didn't exist πŸ’€

An Example:

To check your understanding of the encoding procedure 🧠 suppose we have this portion of a document (1=black, 0=white):

   top row:      0 1 1 1 1 1 0 0 0 0 0 1 1 0 0 0 ...
   bottom row:   1 1 1 1 1 0 0 0 0 0 0 0 0 1 0 0 ...
   -----------   -------------------------------
   state:        1 3 3 3 3 2 0 0 0 0 0 2 2 1 0 0 ...

Suppose also that the black run field length is 2, the white run length is 3, and the state is 1. (This example comes from reference [1].)

This portion would be encoded as:

   1 1011 11 000 1 0100 100 1 0 010 1000 ...

NOTE: Okay, plot twist. The Rapicom 450 sends the bits of a field in reverse order πŸ”„ We'll talk about this in section V. However, since each run length field is sent reversed, the encoded bit pattern above would actually be sent as:

   1 1011 11 000 1 0100 001 1 0 010 1000 ...
                         ^
                         |-this is actually 100 reversed

Another Example:

This example shows the rule for decrementing the run length word lengths πŸ“

   top row:      0 1 1 0 0 1 1 1 1 1 0 0 ...
   bottom row:   1 1 1 1 1 0 1 1 1 1 1 0 ...
   -----------   -----------------------
   state:        1 3 3 1 1 2 3 3 3 3 1 0 ...

Here, let's say the black run field length is now 4, the white is still 3, and the state is 1.

This portion would be encoded as:

   1 1011 0001 1 1 101 0111 011 1 1000 ...
            ^                ^
            |-goes to 3      |-blk cnt goes to 2

When we reverse the order of the run fields, the bit pattern that actually gets sent is:

   1 1011 1000 1 1 101 0111 110 1 1000 ...
           ^
           |-this is actually 0001 reversed, etc.

IV. The Setup Block and the Data Header πŸŽ€

Each data block from the fax machine is 585 bits long πŸ“¦ The number of blocks in a picture is variable and depends on the size and characteristics of the picture. It's worth emphasizing that a block can end in the middle of a scan line of the document 🫢 There can actually be many scan lines in one block.

The 585-bit data block is made up of a 24-bit sync code (used to recognize where a block begins), a 37-bit header, 512 bits of actual data, and a 12-bit CRC checksum ✨

------------------------------------------------------------------
|  24-bit  |    37-bit   |         512-bit         |    12-bit   |
|sync code |    header   |           data          |   checksum  |
------------------------------------------------------------------

The number of useful data bits is variable and can be anywhere between 0 and 512. (There are always 512 bits there, but some of them are to be ignored πŸ™ˆ) The number of data bits to be used is given in the header πŸ’…

The 37 bits of header are made up of:

------------------------------------------------------------------
| 2-bit |5-bit|  10-bit  |   12-bit  |  3-bit   |   3-bit  |2-bit|
|seq num|flags|data count| x position|black size|white size|state|
------------------------------------------------------------------

Here's what each field means 🧁

IMPORTANT NOTE: Most (but not all) of these fields are sent by the fax machine in REVERSE ORDER. The order of each n-bit field must be inverted. Don't skip this one, bestie 😭

Sync code πŸ”

This is used to synchronize on each block. The value of this 24-bit field is 30474730 octal (not reversed).

Sequence number πŸ”’

This number cycles through 0, 1, 2, 3 for the data blocks. It's 0 for the Set-Up block (not reversed).

Flags 🚩

Each of these flags is 1 bit wide:

  • Run: Purpose unknown. It always seems to be 1.
  • Cofb: Purpose unknown. It always seems to be 0.
  • Rpt: 1 for Set-Up blocks (which are repeated when coming from the fax machine, though only one of them is transferred by FAXIE to TOPS20 and stored in the file) and 0 for data blocks.
  • Spare: Purpose unknown. Doesn't matter.
  • Sub: 1 if this is a Set-Up block.

Data Count πŸ“Š

This is the number of useful bits to use out of the 512 data bits. NOT ALL of the 512 data bits are used, only this many of them. This number can be 0 (usually in one of the first data blocks), which means to throw this block away. (This field is reversed!) πŸ™ƒ

X Position

Okay so the scan line position is literally the coolest little number πŸ¦‹ It's a value between 0 and 1725, and it tells you where the next run starts. If the number is bigger than where the last block ended, you fill the gap with white (0's) 🀍 If it's smaller, you jump back there and overwrite the overlapped data with the new stuff from this block. And if it's greater than 1726, you just ignore the field and keep going from where the previous block left off. (This field is reversed!) πŸ™ƒ

Black Size

The black run length field size has to be between 2 and 7 πŸ’… This is the correct value for the black size, and it's allowed to be different from what you saw at the end of the previous block, so don't panic if they don't match. (This field is reversed!) ✨

White Size

Same energy for white! The white run length field size has to be between 2 and 7, and it might not match the end of the previous block either 🀍 (This field is reversed!) πŸ”„

State

This is the current state, and it's the correct one πŸŽ€ It can totally be different from the state at the end of the previous block, which is very much a vibe. (This field is not reversed.) πŸ’œ

Data

This is 512 bits of the actual encoding of the document πŸ“„ NOT ALL of it gets used though. You only use as many bits as the data count says. If this is a set-up block, the data tells you what kind of document you're dealing with (see below) 🧚

Checksum

This is a CRC checksum on the entire block πŸ” It uses the polynomial x**12+x**8+x**7+x**5+x**3+1. Iconic math, no notes πŸ‘‘

In a set-up block, the data portion looks like this:

-----------------------------------------------------------
|   6-bit |    5-bit  |   1-bit  |  20-bits  |  480-bits
|   flags |    spare  |multi page|  of zeros |  1's and 0's
-----------------------------------------------------------

Here's the breakdown, bestie 🫢

  • 6 flags (each is 1 bit):
    • Start bit: Always 0. 🌸
    • Speed: Is 1 if express mode. ⚑
    • Detail: Is 1 if detail mode. (NOTE: If the Detail and Speed flags are both 0, then data is in Quality mode). πŸ”
    • 14 inch paper: Is 1 if 14 inch paper length. πŸ“
    • 5.5 inch paper: Is 1 if 5.5 inch paper length. (NOTE: If the 14 inch and 5 inch flags are both 0, then paper length is 11 inch). πŸ“
    • Paper present: Is 1 if paper is present at the scanner (should be always 1). πŸ“
  • Spare: These 5 bits can be any value. 🎲
  • Multi-page: 1 if multi page mode. πŸ“š
  • Rest of data of set-up block: The above fields are followed by twenty 0 bits, and the rest of the 512 bits of the block are alternating 0's and 1's. πŸ¦“
There are a few super important things to remember about the header of a data block, so pay attention bestie πŸ‘€

First of all, the data count, the x-position, and the black and white run sizes must be read IN REVERSE ORDER πŸ™ƒ The fax machine sends these bits backwards. The sequence number and the state fields are NOT reversed though, so don't mix them up. On top of that, each run field in the data IS REVERSED. Reversing the bits in each n-bit field is totally separate from the reversing and complementing of each octet we talked about earlier πŸ’…

Second, only the first n bits of the data are valid, where n is the value of the data count field (remember it's reversed!). The rest gets ignored πŸ™ˆ If n is zero, the whole block is ignored.

Third, if the x position is beyond where the last block ended, fill the space between where the last block ended and the current x position with white (0's) 🀍 If the x position is less than where the last block ended, replace the overlapped data with the data in the new block. If the x position is greater than 1726, ignore it and continue from where the previous block left off.

Fourth, the black size, white size (reversed), and state (not reversed!) in the header are the correct values, even if they disagree with the end of the previous block. Lowkey the most confident thing in the whole header πŸ’–

Finally, the sequence number (not reversed) should count through 0,1,2,3. If it doesn't, a block is missing 🚨

V. The Decoding Algorithm ✨

Okay, look at the finite state diagram in Figure 1 and you might think decoding is going to be impossible 😭 But it's not! Say you're in the WW state and the next bit is a 1. How do you know whether to go to WB or BW? The trick is that every arc out of the BW state begins with 0, and every arc out of WB begins with 1. So if you're in WW and the next bit is 1 followed by a 0, you go to BW. If the next bit is 1 followed by a 1, you go to WB. It's giving logic 🧠

When you write the decoding program, you need two ways to read the next bit. The first way reads the bit and "consumes" it, which means you move the bit pointer to the next bit. The second way doesn't consume it. Below are four statements that show how to decode fax data. The numbers in parentheses are NOT consumed, so they get read again when you make the next transition πŸ”

If I am in state BW (2) and the next bits are:
   0 (0):             go to BW
   0111:              go to BB
   010 (1):           go to WB
   0100:              go to WW

If I am in state WB (1) and the next bits are:
   1 (1):             go to WB
   1000:              go to WW
   101 (0):           go to BW
   1011:              go to BB

If I am in state  WW (0),  then  first  go through  the run length
algorithm, then if the next bits are:
   0:                 go to BB
   1 (0):             go to BW
   1 (1):             go to WB

If I am in state  BB (3),  then  first  go through  the run length
algorithm, then if the next bits are:
   0:                 go to WW
   1 (0):             go to BW
   1 (1):             go to  WB

For the run length algorithm, remember this: look at the next n bits, where n is the length of either the black or white run length word. REVERSE the bits, and output that many BB's or WW's (depending on whether it's a black or white run) πŸŽ€ If the field is full, increase the size of the word and get that many more bits, meaning get the next n+1 bits, and so on. You can also decrement the run length word length according to the rules in section III. Also, you always go through the run length, even if there's only one WW or BB. In that case the run field will be 0 πŸ™Œ

Let's look at the first example from section III. Say we want to decode these bits (we've already reversed the run lengths to make things easier):

110111100010100100100101000...

We're in state 1 (WB), the black run length word length is 2, and the white length is 3. We get these initial values either from the block header or by remembering them from the previous transitions, if this isn't the start of the block. Following our rules, the string gets parsed like this:

1(1) 1011 11 000 1(0) 0100 100 1(0) 0(0) 010(1) 1000...

The numbers in parentheses were read but not "consumed", so the next number in the sequence is the same as the one in parentheses πŸ‘€ First, we see a 1 and the next bit is a 1, so we go to WB. Then we have 1011, which means go to BB. Next we do a run: we have 11 followed by 000, which means the black run length gets incremented by 1 (it's now 3), and we get 3 MORE BB's. Now we have a 1 followed by 0, which means go to BW. Next, 0100 is WW. Then we have a run, 100, which means four more WW's. We keep going like this and we get back the original bit pattern from the first example in section III πŸ₯Ήβœ¨

It is important to always start fresh with each block. There are a few reasons for this. The first is that blocks sometimes get dropped, and you can recover from that if you resynchronize at the start of each block πŸ”„ Also, if there's about to be a transition at the end of the previous block, the fax machine doesn't make it at the start of the next block. Instead, it gives the new state in the header of the next block and goes from there. So always start at whatever state is given in the header, and line yourself up at the current X position given there too 🎯

Sometimes, while decoding a block, a bit pattern shows up that doesn't match any transition. If that happens, the rest of the block may be bad and should be discarded πŸ—‘οΈ

The decoding program goes through the fax data block by block until it hits an END command in the data, or runs out of data 🏁

VI. Program Performance πŸš€

The L10 NLS program takes about two CPU minutes to run on TOPS20 on a DEC KL10 to decode the average document in fine detail mode πŸ–₯️ In this mode, the picture is about 1726 by 2100 pels, and it takes about 204 disk pages to store.

We have a program that displays bit maps on an HP graphics terminal, and we've been able to display portions of documents πŸ“Ί (Not all of an 8.5" by 11" document will fit in the display.) We can use the terminal's zoom capability to look at very small portions of the document πŸ”πŸ’–

References πŸ“š

[1] Weber, D. R., "An Adaptive Run Length Encoding Algorithm", International Conference on Communications, ICC-75, IEEE, San Francisco, California, June 1975.

[2] Mills, D. L., "Rapicom 450 Facsimile Data Decoding", WP2097/MD33E, COMSAT Laboratories, Washington D.C., undated.

[3] Casner, S. L., "Faxie", ISI Internal Memo, USC/Information Sciences Institute, February 1980.

[4] Postel, Jon, "Rapicom 450 Facsimile File Format", RFC 769, USC/Information Sciences Institute, September 1980.

Appendix ✨

okay bestie, this is the appendix and it's giving sample data era πŸ¦‹ we're showing the first chunk of what comes straight out of the fax machine, with the length and command octets already tacked on πŸ’… all numbers are in octal octets, obviously 🧚

Here's the raw fax output, verbatim:

   114  70 142 171 330  13 377 377 377 371  53 200   0   5 125 125
   125 125 125 125 125 125 125 125 125 125 125 125 125 125 125 125
   125 125 125 125 125 125 125 125 125 125 125 125 125 125 125 125
   125 125 125 125 125 125 125 125 125 125 125 125 125 125 125 125
   125 125 125 125 125 125 125 125 125 121  21 261 114  71 142 171
   330  40   0 102 326 270 152  42  42  44 111   0  42 151 267 122
   366 110 237 102 211 365 111 171 336  51 244 247 377 377 111 362
   177 377 377 377 377 377 377 377 377 376 104 213 241  41 111 377
   111 337 377 377 377 377 377 377 377 377 377 377 377 163 301 361
   377 377 377 377 360 177  12   0 114  71 142 171 330 141 137 177
   377 344  10   0 160  23 301 160 137 376 204 352 135  27 353 264
     0  70 100   7  20  75   0   0   0   0   0 344   0   0   0   0
     0   0   0   0  34 275   0   0   0   0   0   0   0   0   0   0
     0   0   0   0   7  41 310  34 200   0   0 344   0   0   0  71
    13 331 204   0 114  71 142 171 330 241 137  26 302 160   0  16
   100  71   0 370 270 271   0 162   0  71 174 134 100 162   0  34
   234 200 344   7 156 100   1 310  16 107  43 323 263 220 365 313
   327  57 377 325 331  36  56  47 325 324 344   3 227  40  71  35
   200   1 310   1 313 220   0   0   7 241 330   0   0 137 342 200
   114  71 142 171 330 340  77  40 142 160   0   0   0   0 162  71
    73 162 376 276 234 277 376  67 265 301  16  20 171   1 311 313
   346 377 321  75 256 113 245 377 262 160 136 247  13 251 350 374
   270 236 235 217 136 203 220  75 166 166 364 177 305 366  72 107
    63 330 352 345 313 320  71  34 270  46  57   0

next up is that same data after it's been put into RFC 769 format, which means every data octet gets reversed and complemented πŸ”„ it's a glow-up, no cap πŸ’–

   114  70 271 141 344  57   0   0   0 140  53 376 377 137 125 125
   125 125 125 125 125 125 125 125 125 125 125 125 125 125 125 125
   125 125 125 125 125 125 125 125 125 125 125 125 125 125 125 125
   125 125 125 125 125 125 125 125 125 125 125 125 125 125 125 125
   125 125 125 125 125 125 125 125 125 165 167 162 114  71 271 141
   344 373 377 275 224 342 251 273 273 333 155 377 273 151  22 265
   220 355   6 275 156 120 155 141 204 153 332  32   0   0 155 260
     1   0   0   0   0   0   0   0   0 200 335  56 172 173 155   0

   155   4   0   0   0   0   0   0   0   0   0   0   0  61 174 160
     0   0   0   0 360   1 257 377 114  71 271 141 344 171   5   1
     0 330 357 377 361  67 174 361   5 200 336 250 105  27  50 322
   377 343 375  37 367 103 377 377 377 377 377 330 377 377 377 377
   377 377 377 377 307 102 377 377 377 377 377 377 377 377 377 377
   377 377 377 377  37 173 354 307 376 377 377 330 377 377 377 143
    57 144 336 377 114  71 271 141 344 172   5 227 274 361 377 217
   375 143 377 340 342 142 377 261 377 143 301 305 375 261 377 307
   306 376 330  37 211 375 177 354 217  35  73  64  62 366 120  54
    24  13   0 124 144 207 213  33 124 324 330  77  26 373 143 107
   376 177 354 177  54 366 377 377  37 172 344 377 377   5 270 376
   114  71 271 141 344 370   3 373 271 361 377 377 377 377 261 143
    43 261 200 202 306   2 200  23 122 174 217 367 141 177 154  54
   230   0 164 103 212  55 132   0 262 361 205  32  57 152 350 300
   342 206 106  16 205  76 366 103 221 221 320   1 134 220 243  35
    63 344 250 130  54 364 143 307 342 233  13 377

last but not least, here's the first part of the expanded bitmap of this data πŸ–ΌοΈ it's about 4 scan lines, or 2 pairs of scan lines, so it's a small slice but it's giving main character energy πŸŽ€

   177 377 377 377 377 377 377 377 377 377 377 377 377 377 377 377
   377 377 377 377 377 377 377 377 377 377 377 377 377 377 377 377
   377 377 377 377 377 377 377 377 377 377 377 377 377 377 377 377
   377 377 377 377 377 377 367 377 377 377 377 377 377 377 377 377
   377 377 377 377 377 377 377 377 377 377 377 377 377 377 377 377
   377 377 377 377 377 377 377 377 377 377 377 377 377 377 377 377
   337 377 377 377 377 377 377 377 377 377 377 377 377 377 377 377
   377 377 377 377 377 377 377 377 377 377 377 377 377 377 377 377
   377 377 377 377 377 377 377 377 377 377 377 377 377 377 377 377
   377 377 377 377 377 377 377 377 377 377 377 377 377 377 377 377
   377 377 377 377 377 377 377 377 377 377 377 377 377 377 377 377
   377 377 377 377 377 377 377 377 377 377 377 377 377 377 377 377
   377 377 377 377 377 377 377 377 377 377 377 377 377 377 377 377
   377 377 377 377 377 377 377 374   0   4 327 377 377 377 377 377
   374 377 356 377 177   0  10   0 201 200   0   0   0   0 100   0
     0   0   0   0   0   0   1 140   0   0   0   0   0   0   0   0
     0   0   0   0   0   0 204  10   0   0  10   0   0   0 100   0
    20  10   7 250   2   0  57 100 100   2 100 100 164   0  20  21
    31 310 153 137 377 377 377 377 177  32 176 344   2 200 216   0
     4   0 240   0   0  14  70   0   0   0   0   0   2  47 137 336
   137 377 377 377 377 375 377 372  20 140  45 376 377 377 377 237
   377 276 357 377 377 377 227 345 314 175  63 215 202   6 347 143
   377 337 376  70 371 370 352 300 213 373 371 377 377 343  73 334
     0 207 315   3  33 111 377 167 337 377   1 323 365 177 377 177
   377 374 377 135 377 377 365  67 343  55 377 377 377 377 357 377
   377 377 377 377 377 377 203 377 236 175 376 236 337 273 347 377
   376  77 377 377 377 377 377 377 377 377 377 377 300   0   0   0
   200 102 177 377 277 377 377 377 376 377 366 365 173 302  12   0
    40 200   0   0   0   4 100   0   0   0   0   0   0   2   5 354
     0   0   0   0   0   0   0   0   4   0  10   0   0   0 200  10
    40  20   1   0 100   0 140   0  20 210 101 374   3 200 155 304
     0   6 100 103 376   0 120 121  31 332 243 177 377 377 377 377
   377 233 377 354   0 241 217   1  30   0 240   0   0  12 150 202
    40   0   0   0  62  47 157 376 173 373 377 377 377 377 377 377
    20 141 321 376 377 377 377 327 377 376 377 377 377 377 237 216
   316 375 167 215 202   6 300 143 377 237 374  70 175 330 377 304
   255 373 153 377 377 353 377 104   0 267 315 203  13 311 177 377
   377 377   1 223 367 377 373 167 377 376  77 137 377 345 165  67
    43  51 277 377 277 377 357 377 377 377 373 177 377 377 223 377
   366 175 376 234 377 271 347 377 376 157 377 377 377 377 377 377
   377 377 377 377 340   0   0   0   0   0 177 377  37 377 377 377
   377 376 367 357 272 300   2   0   4   0   0   0   0   0   0   0
     0   0   0   0  20   0   1 144   0   0   0   0   0   0   4   4
     0   0 100   2 100  10 201  10   0  20  75   0   0  40 142   0
     0  74 341 234 103   4 157 300   0   2   0 141 372   0   0  20
    30 376  55 277 177 377 377 367 377 371 376 100  15  61  16 200
    30   0  40   0   0   0 311 200  24   0   0   0  62  55 377 316
   367 347 377 357 377 377 377 377 170 305   5 276 377 377 377 357
   377 377 377 377 377 177 377 377 357 177 377  76 207 246 340 147
   376 336 356  10  17 320 105 235 275 377 377 373 377 347 335 317
    50  77 377 353  75 333 377 377 377 377 363 337 343 277 356 171
     7 357  76 216 377 211 207 176 257 217 377 377 367 357 357 277
   377 357 377 377 377 375 367 377 377 377 377 375 377 377 356 377
   366 377 377 377 377 377 377 377 377 377 377 377 340   0   0   0
     0  44 373 377  77 377 377 177 177 377 377 337 376 170 173   0
     0   0 100   0   1  10   0   0   0   0   0 200 160   0 223 160
   300   0   0   0   0   0   0   6 100 220   0   0 140   4   3  30
   121  20 351 300 206  74 167   0  30  64  41 234 172  30 175 300
     4  32   4 345 367 200 103  60 177 372 177 233 377 377 377 377
   376 125 207 210 233  21 364 361 277   1  50  16 140 120  41 335
   377 306 214  10  67 377 373 377 377 377 377 377 377 367 377 377
   377 363 277 377 377 377 377 377 267 177 377 377 377 377 377 237
   377 377 377  77 377 377 355 373
RFC>>>

that's the whole appendix, bestie πŸ’œβœ¨ you're literally a bitmap-decoding queen πŸ‘‘πŸŒˆ

πŸ“¦ where this page comes from