CAPS Universe documentation  1.0.4
All you need to know to be successful
The Printer Data Encoding Method "1030"

The 1030 encoding method is line oriented, data is sent in blocks of data, which in turn forms a band. A band is what the printer prints at once.

In the wire data (regular PCL5) this kind of data starts with a leading ESC+*b1030m, then the encoded printer data follows and it is terminated with a 1030M+FORM-FEED. The data inbetween both markers describes a full page.

The data inbetween both markers is organized in bands of n lines each (the real count depends on the printer model and its available memory). The wire data for a band is sent in blocks. Each block can consists of at most n lines or at most C1030_MAX_BYTES_IN_ONE_BLOCK bytes. Whenever a block reaches one of these limits, it gets send to the printer with the following leading command:

  • sum of all bytes after the following char (as decimal ASCII)
  • the char 'w'
  • struct cm1030_block_header and the encoded line data

Example:

"16352w" which means the data after the 'w' is 16352 bytes in size

At least one data block is required to define a band. In this case it provides all n lines to the printer at once. But if a data block hits the C1030_MAX_BYTES_IN_ONE_BLOCK bytes limit, it carries less then the n lines for the band. In this case more data blocks are needed to fill up the n lines of the band.

If n is 128 for example, we can send two 64 lines data blocks or four 32 lines data blocks to define the band. Or we can send a 100 lines data block plus a 28 lines data block.

Note
We cannot send a 100 lines data block plus an 80 lines data block. In this case the printer skips 52 lines from the second data block, which are above the 128 line limit of a band.
Attention
Each data block needs to contain complete lines. E.g. you cannot send a line partially, due to some still available bytes at the end of the data block
Each first line in a data block needs to be encoded without a reference line
Each band must have the full count of lines to be printed, else it gets skipped. If the band contains less than the required lines, you need to fill it up with empty lines in order to print the intended lines.

Each line is a list of 'edits', while the first entry in the line is always the count of 'edits' which follows for this line. The count of 'edits' in a line can be '0' (e.g. C1030_LINE_IS_EQUAL) which means for the current line no edits are required and the previous line's content can be used again unchanged. The 'edit' count values 1…254 are regular count values to define the count of the following 'edits', while 255 has another special meaning: this line is empty (e.g. all bits zero).

The compression of printer data works by using a single line buffer at the printer's side. Whenever we start the next line, we have the content of the previous line still in the buffer and can now replace ('edit') its content via fixed data (substitute edit) or repeating pattern (repeat edit) to form the next line.

Both types of entries using 'offset' and 'count' to work on a specific part of the line buffer. Thus, we can still have the previous content in the buffer and just change the parts which are different in the new line's buffer. E.g. the printer driver sends the line delta only.

If someone thinks, "Hey, this encoding of the substitute edit and the overflow handling rings a bell in me!". Yes, it's borrowed with modifications from the PCL mode '3' (aka "line delta encoding", refer The Printer Data Encoding Method "3" for details).

Data in each 'line':

<one byte for edit count> 0x00…0xff
  • Values are 1…254: 1…254 'edits' follow.
  • Value is 0: no edit follows, use the line as-is (e.g. same as the previous one)
  • Value is 255: no edit follows, the whole line is empty.

Data in each 'edit':

Each first 'edit' byte defines the type of 'edit' in its bit 7:

<0x80 | info> Repeat entry
<info>        Substitute entry
Note
Each line begins with a line offset of 0, which is incremented by each 'edit' and is used as the base for the next 'edit' in the same line.

Repeat edit

One possibility to encode the data sent to the printer is to find repeating bytes in the input data. In this case it is possible to just send the repeating byte and its repeat count. This can be encoded into two bytes. So its worth the effort if more then two consecutive bytes in the input data are matching.

7654 3210
1ooc cccc
   ^_^^^^_ (Part of) 'count'
 ^^_______ (Part of) 'offset'

If offset == 0b11 then 'overflow' bytes follow, which must be added to the 'offset' value.

Examples for the 'offset' (this must calculated first):

111x xxxx 1111 1111 0001 0000  <pattern>
                    ^^^^_^^^^_ Overflow terminator at the same time
 ^^_______^^^^_^^^^_^^^^_^^^^_ Offset sum is: 3 + 255 + 16

111x xxxx 0001 0000 <pattern>
          ^^^^_^^^^_ Overflow terminator at the same time
 ^^_______^^^^_^^^^_ Offset sum is: 3 + 16

If 'count' == 0b11111 then 'overflow' bytes follow, which must be added to the 'count' value.

Examples for the 'count' (this must calculated second, after the 'offset'):

1111 1111 0001 0000 0000 0111 <pattern>
                    ^^^^_^^^^_ Overflow terminator for the 'count' at the same time
          ^^^^_^^^^___________ Overflow terminator for the 'offset' at the same time
 ^^_______^^^^_^^^^___________ Offset sum is: 3 + 16
   ^_^^^^___________^^^^_^^^^_ Count sum is: 31 + 7, to be used value is: 31 + 7 + 2

This kind of 'edit' will now fill the line with (repeated) <pattern> beginning at the line offset + 'offset' from this 'edit' 'count' times. After doing so, the line offset gets incremented by 'offset' + 'count' (to be used by the next 'edit' as its new base).

Substitute edit

A second possibility to encode the data sent to the printer is to find parts of the current line which differs from the previous line. Only these different bytes are sent to the printer.

 7654 3210
 0ooo occc
       ^^^_ (Part of) 'count'
  ^^^_^____ (Part of) 'offset'

If offset == 0b1111 then 'overflow' bytes follow, which must be added to the 'offset' value.

Examples for the 'offset' (this must calculated first):

0111 1xxx 1111 1111 0001 0000  <data> …
                    ^^^^_^^^^_ Overflow terminator at the same time
 ^^^_^____^^^^_^^^^_^^^^_^^^^_ Offset sum is: 15 + 255 + 16

0111 1xxx 0001 0000 <data> …
          ^^^^_^^^^_ Overflow terminator at the same time
 ^^^_^____^^^^_^^^^_ Offset sum is: 15 + 16

If 'count' == 0b111 then 'overflow' bytes follow, which must be added to the 'count' value.

Examples for the 'count' (this must calculated second, after the 'offset'):

0111 1111 0001 0000 0000 0111 <data> …
                    ^^^^_^^^^_ Overflow terminator for the 'count' at the same time
          ^^^^_^^^^___________ Overflow terminator for the 'offset' at the same time
 ^^^_^____^^^^_^^^^___________ Offset sum is: 15 + 16
      ^^^___________^^^^_^^^^_ Count sum is: 7 + 255, to be used value is: 7 + 7 + 1

This kind of 'edit' will now fill the line with 'count' bytes beginning with <data> at the line offset + 'offset'. After doing so, the line offset gets incremented by 'offset' + 'count' (to be used by the next 'edit' as its new base).

The raster data is expected as:

  • one bit per pixel (monochrome)
  • leftmost pixel is bit 7
  • a bit to print is '1'
Note
This encoding is also described in the corresponding manuals for the HBP mode. But the other printer commands in HBP mode differ from the PCL commands used here to enter the 1030 mode and transfer the data block.