agalakhov / captdriver

Driver for Canon CAPT printers
GNU General Public License v3.0
143 stars 62 forks source link

LBP-1120 not supported #20

Open okias opened 5 years ago

okias commented 5 years ago

If any debug required, please let me know, I'll try help as much I can.

Dist: Ubuntu 19.04

agalakhov commented 5 years ago

I currently do not own any printer of LBP family so I'm unable to check anything. If you can tell what has to be changed, I'll assist you.

Regards, Alexey

itspec-ru commented 4 years ago

Та же проблема. Для LBP-1120 использую Canon-LBP2900.ppd При печати cups сообщает "CAPT: unknown printer":

D [09/Jul/2020:13:47:06 +0400] [Job 5430] CAPT: rastertocapt started
D [09/Jul/2020:13:47:06 +0400] [Job 5430] CAPT: printer ID string MFG:Canon;MDL:LASER SHOT LBP-1120;CMD:CAPT;VER:1.0;CLS:PRINTER;DES:Canon LASER SHOT LBP-1120
D [09/Jul/2020:13:47:06 +0400] [Job 5430] CAPT: detected printer \'LASER SHOT LBP-1120\'
E [09/Jul/2020:13:47:06 +0400] [Job 5430] CAPT: unknown printer \'MFG:Canon;MDL:LASER SHOT LBP-1120;CMD:CAPT;VER:1.0;CLS:PRINTER;DES:Canon LASER SHOT LBP-1120\'
D [09/Jul/2020:13:47:06 +0400] [Job 5430] Set job-printer-state-message to "CAPT: unknown printer \'MFG:Canon;MDL:LASER SHOT LBP-1120;CMD:CAPT;VER:1.0;CLS:PRINTER;DES:Canon LASER SHOT LBP-1120\'", current level=ERROR

Я что-то делаю не так или действительно LBP-1120 не поддерживается?

ra1nst0rm3d commented 3 years ago

До сих пор не можем?

agalakhov commented 3 years ago

LBP-1120 is quite different from other printers of LBP family. It is an early model. While the driver has all of necessary components to support it, nobody wrote the corresponding glue code.

ra1nst0rm3d commented 3 years ago

Why you don't copy compress code from Nicolas Boichat's driver?

agalakhov commented 3 years ago

It's about control code, not compress code. All LBP printers are controlled differently.

Nicolas Boichat's driver does not have any control code at all. It just sends magic blobs to the printer with zero knowledge about their meaning. Now we know what most of their bytes mean. One has to implement the correct handshake.

Supporting compression itself is pretty straightforward.

ra1nst0rm3d commented 3 years ago

How to reverse compression algorithm?

ra1nst0rm3d commented 3 years ago

I tried to use your work in the'anticapt' repository and i don't understand how to use ur captdefilter. You need to write help info

agalakhov commented 3 years ago

The compression algorithm is already reversed. That's how it's described:

41 syntax
--
End of line (don't change the buffer)
--

Simple bytes:

00 syntax (1-7 bytes)
---
00MMM000 M bytes

11 syntax (8-255 bytes)
--
101MMMMM 11MMM000 M bytes

Repeated bytes:

01 16p->56p
--
01NNN000 XXXXXXXX
N*(X pattern)

11 16p->56p +8 (3 bytes)
--
11NNN001 XXXXXXXX YYYYYYYY
N*(X pattern) + Y pattern
--

101 64p->2040p +8
--
101NNNNN 00NNNMMM XXXXXXXX M bytes
N*(X pattern) + M bytes (0-2, maybe more)

This seems to describe SCoA completely.

ra1nst0rm3d commented 3 years ago

I don't understand this document)

agalakhov commented 3 years ago

I'll explain. It is known how the bitstream is decoded.

Byte 00mmm000 followed by mmm arbitrary bytes (where mmm is a 3-bit number from 1 to 7) is decoded just in these mmm bytes.

Bytes 101mmmmm 11mmm000 followed by mmmmmmmm bytes (where mmmmmmmm is a 8-bit number from 8 to 255) is decoded in just these mmmmmmmm bytes.

(In fact, one could implement "fake" compression by just using these two expressions. The printer will understand this but will work terribly slow.)

Byte 01nnn000 followed by exactly one byte is decoded into nnn repeats of this byte. Byte 01nnn001 followed by exactly two bytes is decoded into nnn repeats of the first byte followed by the second byte.

The document does not mention this, but I would extrapolate that 01nnnmmm followed by one byte, then mmm bytes is decoded into nnn repeats of the first byte followed by mmm non-repeated bytes. One could check this with the printer.

The combination 101nnnnn 00nnnmmm seems to work in similar way for longer patterns.

The byte 0x41 repeats the whole last line.

ra1nst0rm3d commented 3 years ago

What contains mmm number? And, 8-bit number is a single char, right?

agalakhov commented 3 years ago

In the bit stream numbers are sometimes split between multiple bytes. Small numbers are encoded just as three bits. For example, to encode a byte repeat 1 to 7 times we write the byte 01<three bits repeat count>000, then the byte to be repeated. 8-bit numbers are split into 5+3 bits parts, see above examples. 101mmmmm 11mmm000 means that we're splitting mmmmmmmm in two parts across two bytes. In first byte it is prefixed by "101" and in second byte it is prefixed by "11" and suffixed by "000".

This is pretty straightforward approach if you're worked with any bitstream-based (i.e. Huffman) encodings before.

ra1nst0rm3d commented 3 years ago

But why split the number into parts, isn't it easier to write an 8-bit number and initialize the repetition counter? And what goes in input: PostScript or raw text?

ra1nst0rm3d commented 3 years ago

Wow... I, maybe, can base SCoA compression on Hi-SCoA codebase...

ra1nst0rm3d commented 3 years ago

@agalakhov, можете вы описать алгоритм в SPECS как вы это сделали с Hi-SCoA, чтобы мне было проще писать. Все что вы выше описали - это понятно, но этой информации для меня недостаточно

agalakhov commented 3 years ago

Splitting numbers into parts is done to spare bytes. If we only need small numbers, we only need one extra byte: it has enough place for 2-bit message code and two 3-bit numbers. If we need more than 3 bits for a number, first 3 bits are sent just like above and remaining 5 bits are sent in the second byte. There are some spare bits, they could have some meaning too or used just for redundancy.

I wrote the Hi-SCoA code with SCoA in mind. The reason there is no SCoA in the code is, I can't test it.

The reason I don't write the documentation in SPECS is, I didn't test it myself. If I understood something incorrectly, I don't want to document my guesses instead of proven facts.

The simplest way to check if the printer works at all is, just send uncompressed data using the "send 7 bytes" command. Get it working for small messages, then improve the compression. The tricky part is NOT the compression. It's the command level. Especially for older SCoA printers you do NOT send the whole page at once. The printer does not have enough memory for it. You send smaller bands and poll for the printer status after each band.

ra1nst0rm3d commented 3 years ago

Fucking CAPT, and it's creator - Canon

agalakhov commented 3 years ago

This is the worst printing protocol I've ever seen. And this is the only printer family that needs bidirectional communication during printing. All others, even low-cost WinPrinter inkjets, only need the page to be sent to them in some special format. Never buy Canon LBP if you have any alternatives.

Surprisingly, Canon's inkjets use sane protocol.

ra1nst0rm3d commented 3 years ago

xorval? What it should contain for SCoA?

agalakhov commented 3 years ago

Zero.

ra1nst0rm3d commented 3 years ago

I would simply compress band?

agalakhov commented 3 years ago

Older printers require just compressed bands, one band at a time. No XOR is done. Looks like XOR is just some kind of obfuscation.

ra1nst0rm3d commented 3 years ago

I've find in capt_command.h switch CAPT_SET_PARM_HISCOA. Should I set CAPT_SET_PARM_SCOA and what it should contain?

ra1nst0rm3d commented 3 years ago

mmm bits is raw data?

agalakhov commented 3 years ago

Yes, mmm are just 3 raw bits.

The CAPT_SET_PARM_HISCOA command and others are described in SPECS. We don't know any more. If some field is described as "unknown", it is really unknown.

ra1nst0rm3d commented 3 years ago

I should make it to push "mmm" byte: push_bits(state, 0x5, 3); push_bits(state, mmm, 3); push_bits(state, 0x3, 2); push_bits(state, mmmm, 4); push_bits(state, 0x0, 3); Right?

agalakhov commented 3 years ago

Yes, something like that.

ra1nst0rm3d commented 3 years ago

@agalakhov please give me a hex desc of all SCoA commands

agalakhov commented 3 years ago

I don't have it.

ra1nst0rm3d commented 3 years ago

What is longrepeat? it's very big repeating of last byte?

agalakhov commented 3 years ago

It is repeat of given byte that does not fit into "short repeat".

ra1nst0rm3d commented 3 years ago

maybe u write realization on YOUR code and I test it?

ra1nst0rm3d commented 3 years ago

@agalakhov I need to push hiscoa_params on SCOA realization?

ra1nst0rm3d commented 3 years ago

@agalakhov pushed initial port SCOA compression. Check it) https://github.com/ra1nst0rm3d/captdriver