Search code examples
decodeencodeepsonescpos

Decode Epson print (ESC-i) command decoding/encoding


I'm trying to understand the algorithm used for compression value = 1 with the Epson ESCP2 print command, "ESC-i". I have a hex dump of a raw print file which looks, in part, like the hexdump below (note little-endian format issues).

000006a  1b  (  U 05 00 08 08 08 40 0b 
         units; (page1=08), (vt1=08), (hz1=08), (base2=40 0b=0xb40=2880)
...
00000c0 691b 0112 6802 0101 de00
        esc i 12 01 02 68 01 01 00
        print color1, compress1, bits1, bytes2, lines2, data...
          color1 = 0x12 = 18 = light cyan
          compress1 = 1
          bits1 (bits/pixel) = 0x2 = 2
          bytes2 is ??? = 0x0168 = 360
          lines2 is # lines to print = 0x0001 = 1
00000c9                       de 1200 9a05 6959
00000d0 5999 a565 5999 6566 5996 9695 655a fd56
00000e0 1f66 9a59 6656 6566 5996 9665 9659 6666
00000f0 6559 9999 9565 6695 9965 a665 6666 6969
0000100 5566 95fe 9919 6596 5996 5696 9666 665a
0000110 5956 6669 0456 1044 0041 4110 0040 8140
0000120 9000 0d00
                  1b0c 1b40 5228 0008 5200 4d45
                    FF esc @ esc ( R 00 REMOTE1

The difficulty I'm having is how to decode the data, starting at 00000c9, given 2 bits/pixel and the count of 360. It's my understanding this is some form of tiff or rle encoding, but I can't decode it in a way that makes sense. The output was produced by gutenprint plugin for GIMP.

Any help would be much appreciated.


Solution

  • The byte count is not a count of the bytes in the input stream; it is a count of the bytes in the input stream as expanded to an uncompressed form. So when expanded, there should be a total of 360 bytes. The input bytes are interpreted as either a count of bytes to follow, if positive, in which case the count is the byte value +1; and if negative the count is a count of the number of times the immediately following byte should be expanded, again, +1. The 0D at the end is a terminating carriage return for the line as a whole.

    The input stream is only considered as a string of whole bytes, despite the fact that the individual pixel/nozzle controls are only 2 bits each. So it is not really possible to use a repeat count for something like a 3-nozzle sequence; a repeat count must always specify a full byte 4-nozzle combination.

    The above example then specifies:

      0xde00  => repeat 0x00 35 times
      0x12    => use the next 19 bytes as is
      0xfd66  => repeat 0x66 4 times
      0x1f    => use the next 32 bytes as is
      etc.