CANON CARPS (Canon Advanced Raster Printing System) print format
(reverse-engineered from LaserBase MF5730)
Hacking resulted in a working CUPS driver: CARPS-CUPS
Data is organized into blocks, each with 20-byte header:
0: 0xCD - magic value 1: 0xCA - magic value 2: 0x10 - magic value 3: data type (0x00 = control data, 0x02 = print data) 4: 0x00 5: block type (0x11, 0x12, 0x13, 0x14, 0x16, 0x17, 0x18, 0x19, 0x1a) 6: 0x00 7: 0x01 8: length (high byte) of data following the header (number of bytes) 9: length (low byte) 10-19: padding (zeros)
maximum block (URB?) size is 4KB (4096B)
DOCUMENT structure
Document consists of blocks in this order:
0x11: ???: 13 bytes: \x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00 0x12: document name: \x00\x04\x00\x11 + character count + name 0x12: user name: \x00\x06\x00\x11 + character count + name 0x12: ???: 10 bytes: \x00\x09\x00\x00\x07\x00\x00\x00\x00\x00 0x14: ???: 4 zero bytes 0x17: ???: 4 zero bytes 0x18: ???: 5 bytes: \x00\x2e\x82\x00\x00 0x18: image refinement: 3 bytes: \x08\x2d + \x01 (off) or \x02 (on) 0x18: toner save: 3 bytes: \x08\x5a + \x01 (off) or \x02 (on), if this block is not present, "printer default" is used PRINT DATA HERE 0x1a: end of print data: 1 byte: \x01 0x19: 0 bytes 0x16: 0 bytes 0x13: end of document: 1 zero byte
PRINT DATA structure
all print data is in blocks with data type 0x02, block type 0x1a
each page begins with a header (first page has header in separate block, others don’t (?)), such as:
\x01.%@.P42;600;1J;ImgColor.\.[11h.[?7;600 I.[20't.[14;;;;;;p.[?2h.[1v.[600;1;0;32;;64;0'c
P42: ??? 600: 600dpi (300 = 300dpi) 1J: ??? ImgColor: ??? 20't = Plain paper (15't = Plain L, 20't = Plain, 30't = Heavy, 35't = Heavy H, 40't = Transparencies, 55't = Envelope) 14 = A4, 16 = A5, 30 = letter (??????????????), 60 = envelope monarch 1v: 1 copy (2v = 2 copies, 99v = 99 copies)
then page data follows in STRIPs, each STRIP in one or more blocks
each STRIP includes a header, such as:
\x01.[;4724;110;15.P
4724: strip witdh (in dots) for A4 (letter = 4863), 2362 (A4 300dpi) 110: strip height (in dots) (minimum is 1, maximum 110) 15: ???
then COMPRESSED DATA HEADER follows (13 bytes):
0: 0x01 - magic value 1: 0x02 - magic value 2: 0x04 - magic value 3: 0x08 - magic value 4-5: 0x0000 6: 0x50 - magic value 7: 0x00 8: last strip indication (0x00 = last, 0x01 = not last) 9-10: length (little endian??) - number of following data bytes (excluding ending 0x80 byte), can span multiple blocks, subsequent blocks do not have this header 11-12: 0x0000
then COMPRESSED DATA follows
strip can span multiple blocks (next blocks are without any headers)
strip ends with 0x80 byte
line ends with zero byte (1111 1101)
compression is per line (repeat stream can’t pass line end)
each page ends with a 2-byte block containing \x01\x0c
print data ends with a 7-byte block containing \x01\x1b\x50\x30\x4a\x1b\x5c
COMPRESSED DATA format
All data bytes in compressed blocks are XORed by value 0x43.
Compression works on byte level (with respect to print image data – each byte represents 8 dots on page) but the encoding is bit-level. There are 5 compression methods:
- Repeat bytes from this line at offset -80 bytes
- Repeat bytes from this line at offset -2 bytes
- Repeat bytes from this line at offset -1 byte (= last byte)
- Repeat bytes from -3rd or -7th previous line
- Get a byte from dictionary
Dictionary is 16 byte long - Zero byte
0b11111101 - Byte immediate (no compression)
0b1101
0bxxxxxxxx (data)