-
Notifications
You must be signed in to change notification settings - Fork 60
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
SCoA Printers #33
Comments
I need a volunteer who has a SCoA printer and can program for that. |
I has LBP1120 and may code on C/C++ |
Just leaving this link just in case it would be useful to anyone else who also wants to have a go at implementing SCoA: https://github.com/caxapyk/capt_lbp810-1120 It's a fork of the original Nicolas Boichat driver for the LBP-810, which contains an SCoA implementation. |
No, as say @agalakhov its don't realizing SCoA compression |
Oh, I didn't know that Nicolas' driver wasn't complete 😞 For those coming from Google or the future: see also #20 |
You're wrong. It DOES implement SCoA compression. But it does not handle control commands correctly. It just sends "magic sequences of bytes" without knowing anything about their meaning, which is not always correct. To get an idea:
Now we know that this configures paper dimensions, toner saving mode and paper thickness. Nicolas did not know that and just hardcoded the values he had on his configuration. They're wrong for some users. The actual documentation of SCoA compression is in SPECS file and seems to be complete. The driver contains a working SCoA compression example (but please don't just copy and paste this code, it requires huge refactoring). |
Very useful info, thx |
👉 EDIT: the SCoA specs now have a page in my wiki, please check it out for more info. @agalakhov I have been trying to understand SCoA for the past week, and I think I am beginning to get it. From what I figure:
Is my understanding correct, or am I way off? Footnotes |
@mounaiban Relying on Nicolas' code, looks like you on right way) U will be very useful) Thanks for your research) |
It looks more or less correct. SCoA commands are not very consistent. There is a "simple" possibility to check how it works. There is a binary in the stock closed-source Linux driver called "captfilter". Calling it with correct parameters generates a print job with some (not all) A0 commands and with correct compressed pages. You can then try to decompress the output based on your guesses and check if it is decompressed correctly. Look at https://github.com/agalakhov/anticapt/blob/master/filter.sh |
@mounaiban I have some question for you)
|
@ra1nst0rm3d In the Copy command, @agalakhov Thanks for the tip on the |
No, I understood you, thx. |
@mounaiban Found some interesting commands from disassembled code of captfilter.
There can be some Hi-SCoA commands. |
I'll just document this here before writing up a wiki page: Generating SCoA/CAPT print data using
|
@agalakhov Just a quick question: do you flip bytes in the SCoA bitstream? Or is it just the command and the packet size that's flipped to little endian? For example, in the output of Do you read it as |
The stream is little-endian. My code tries to be machine-endianess-agnostic. The stream is always read byte-by-byte. Then, if we need an integer value of more than one byte, it is assembled in little-endian byte order. That is, if we have
and have to interpret it as
we get
on both little-endian and big-endian machines. |
We may have discovered a few more things about the SCoA format, particularly a few new opcodes and the usage of the line buffer. Long Repeat only Command
This command appears to repeat operand A into the line buffer, without any uncompressed suffix. It might have the same effect as Long Repeat and Short Copy Line Buffer UsageBoichat's SPECS document doesn't contain a detailed explanation of how the line buffer works, but it mentions Here's how I think the SCoA line buffer works:
Here are some things I don't know: a. What is printed when you do a b. What happens if one fails to c. Does the buffer pointer reset to zero after a Line Buffer Pointer Opcodes and Delta EncodingThere are a few extra opcodes that cause the pointer to skip towards the right, but I don't yet know the exact format of the opcodes. As far as I can tell, there are two "skip right and place raw byte" opcode (one short one long) and one "skip right only" These opcodes are used to implement some kind of delta encoding when a line is similar to the previous one; instead of encoding the entire line, you can seek to where the line changed and patch. |
@agalakhov Thanks, I understand it now that there's nothing to flip in the bitstream/payload. |
@mounaiban About three opcodes for A4 line buffer. It's looks like this?
|
@ra1nst0rm3d Well done, you have just drawn a complete blank line across an A4 sheet! 💯 Also: |
@mounaiban Can you rebuild your opcodes table with new information? This will help me to write compressor. P.S Hmm... Can we just build first line, then push it to printer, get next line and check differences between them? P.P.S Can we just init buffer every single band and push data to initialized buffer? P.P.P.S This looks strange...
|
@ra1nst0rm3d I have compiled all known SCoA opcodes into a single document in my wiki, have fun! I think you are meant to work on it like they do with video compression: start with a "key" line that encodes the whole line, then make "delta" lines that take the previous line and change it. Also try compressing a sample that looks like this, using captfilter: The sample makes use of all the opcodes we know so far... P.S. I will look at the code later, I'm only getting started with this thing 😅 |
This is an urgent update about the
This incidentally is an answer to the contradiction that arises under the initial understanding of If 0x9f meant adding 256 bytes, Sorry if you got stuck, as this misunderstanding could be why you got stuck. I will update the wiki and my previous significant comments soon. Notes about the function names found in the captfilter disassemblyAlso, I think I am beginning to understand the names found in the disassembly for captfilter earlier in this thread. Canon uses the words 'Raw', 'Repeat' and 'Copy'. While 'Repeat' is obvious, 'Raw' could mean 'uncompressed bytes' and 'Copy' could mean 'copy from the line buffer', contrary to the terminology I have been using so far. To avoid potentially contradicting the original terms, I'll just use From my understanding of Hi-SCoA, I think there's just one big adaptive uncompress command. LZ77 (which Hi-SCoA is a specialisation of) attempts to compress everything; repeated segments don't have to be contiguous in LZ77, so there is no need for separate uncompressed and compressed segments and their separate commands. |
@mounaiban captdriver works on FreeBSD with CUPS: printer responds on commands sent to him. Nicolas' driver don't work, because bug in kernel. |
@mounaiban Can you generate PPD file for LBP1120? I think, I has some errors in this thing. |
@ra1nst0rm3d Thanks for testing the driver on FreeBSD. It's really great to know we can run on BSDs 👍 As for the PPD, what errors are you getting? The PPD from your fork compiles on my test Ubuntu (14.04.6) system just fine. |
In the meantime I think I might have discovered more opcodes (or rather, new ways to use the ones we already know). This is just a provisional list, we will find out for sure only once the SCoA decoder is done.
Watch out for the A's and B's... in some opcodes B comes first! Now that we have an interpretation for 13/14 opcodes, it's time to test the living daylights out of this thing... we still don't have a place for Footnotes |
@mounaiban Your new table approves my write_simple_byte() and try_write_byterepeat() implementation. |
@ra1nst0rm3d I saw your commits over the past week, and it looks like it has a working SCoA and CAPT 1 implementation. Did you manage to print? And what the hell is Numba? It's possessed! 🐍 💨 |
@mounaiban I tried, but it won't work at all) |
@ra1nst0rm3d is the upper left corner of the picture the upper right of the page? Maybe the printer is not getting the correct line width or image size? That's my wild guess seeing how the pixels are staying on one side of the page and going off the bottom while staying the same width throughout... My other guess is that the printer is not getting the correct code for long runs, but I think this is less likely 🤔 I am also questioning my understanding of old_Long + new and old_Long + repeat; I suspect that
contrary to the table above. Try the above interpretations if the current table doesn't seem right... |
I have just added a SCoA decoder to the studycapt repo, but it's not quite working correctly yet. I'm trying to figure out if there was an error in the data extraction from the captfilter job files or if our understanding of the algorithm is still not 100% correct. This is an attempt to decompress the circle sample page: Note that the circle has been squashed, and the glitched lines are remarkably consistent. The black region at the bottom indicates missing pixels. Were long runs cut short? I don't know yet, but I may have made my first NFT 🤑 |
@mounaiban Thanks for your SCoA decompressor) This will give a huge impact to development) |
@ra1nst0rm3d You're welcome 😄 The latest fix as of mounaiban/studycapt@ef9c0d1 improves the accuracy of the decompression, but we're still not 100% (which we need, because lossless) There is one opcode that's eluding me: in the A4-sized circle sample from If that is the case, everything I thought I knew about |
Circle not full black? If it full black, pixel data will be 'ff'. |
This is how we unpack Update: what I said earlier, I take that back. Check this post history for the original version.
Our mystery of the week (hopefully we can solve it in a week) is: what does |
@ra1nst0rm3d The circle is fully filled black. The test page is generated by sample_blots.py:
The sample is then compressed with: Currently at a loss trying to figure out these mystery opcodes that Because my decompressor doesn't handle them, they cause the wrong bytes to be repeated or passed, and the remaining data gets misinterpreted as opcodes. The mystery opcodes aren't always I hope these mystery codes aren't needed to make the printer usable... |
Sorry, but I'm suspending development of captdriver to ~middle of Jule, because I'm giving final exams on school and I'm going to university this autumn :) Maybe, I will push some my decisions to my fork, but it will be a bit unstable. P.S Good luck, @mounaiban. I think, that you discover all opcodes and I write final version of SCoA compressor |
@ra1nst0rm3d All the best for your exams! 🖖 |
I believe we have found another opcode, and it's the longest one so far 🦒 : I'm inclined to call it This also solves this week's Mystery Opcode: This has been verified with the original uncompressed A4 600dpi circle sample. The sixth line of the circle is 287px long, and from our mystery opcode, 35 * 8 == 280. There are seven more pixels from the following opcode which places a single SCoA Decoder WIPUPDATE: We have successfully decompressed test samples. The SCoA decoder now works correctly on test samples at time of writing. Further work on the decompressor is expected to be mostly validation! validation! validation!👏 and will continue as far as long as this driver is relevant.
|
I passed my first Unified State Exam in the russian language. It's been very easy! |
@ra1nst0rm3d Well done, sounds like you were well prepared for your exams! ✌️ There's yet another opcode, and I'd call it The instruction bit layout is like: I will post the updates when I get the chance... |
Can we assume that second bit of third byte switch between new and repeat? |
If you are thinking one bit at a time and in terms of binary trees, yes. SCoA appears to be a prefix, variable-length code. The funky opcode numbers might be a way of making sure the opcodes are easy to process, without confusing them for another code, when reading one bit at time. I didn't use the "correct" approach with my SCoA decoder. When decoding, I think the decompressor is supposed to use a function pointer binary tree to switch between decompression operations. Reading one bit at a time, the bits determine how the tree is navigated. I might do that for a C implementation someday... |
Just when I thought we knew all the opcodes, another new one turns up... I'll call this one repeat + new_Long, and it looks like But wait, there's more! The old + new_Long: old + repeat_Long: UPDATE: the SCoA decoder is now pretty much beta-quality AFAIK, I have been able to decompress all of my test samples so far. The SCoA specs on my wiki have also been updated. Hopefully, we have completely charted the SCoA and preserved the specs for future generations, like just in case someone stumbles upon an LBP800 in 2077... |
Is anyone still interested in adding LBP-810/1120 support into this driver? @mounaiban, maybe? |
Thanks for reaching out @ValdikSS; LBP-810 and 1120 (and possibly LBP3200) support is still part of the master plan, but we're just short on time. I don't know when we will be able to get back onto working on the driver, but in the meantime, I have updated the SCoA Specifications, particularly on the treatment of previous lines, to hopefully be easier to read. @ra1nst0rm3d has made a fork specially for working on SCoA support. The driver was reportedly able to communicate with the printer, but the output was not correct. Maybe give it a try if you know C programming? |
I've ended up writing my own pbmraw → CAPTv1 converter as a replacement for proprietary By the way, CAPT implementation from Boichat Nicolas produces incorrectly encoded stream (sporadic black lines, also detected by your decoder). Haven't tried @ra1nst0rm3d encoder or lbp800 encoder. |
@mounaiban, how could I contact you in private? Your email is hidden in the commits. Please write me at [email protected] |
@mounaiban |
@ValdikSS thanks, I've updated the specs. Sorry I haven't had the time to open up an email for inquiries for my projects, but I feel that I have to do pretty soon; there are some issues that aren't really meant to be publicly discussed... 🙊 |
@mounaiban, I'd like to offer paid captdriver improvement for you (or any other developer willing to do that job). |
@ValdikSS to go faster than 30s/page, you might have to encode the page at the rasteriser as the pixels are being output, which means writing a Ghostscript device. As for payment, I don't feel it's the right time to accept payment or donations as the driver isn't quite consumer-friendly yet. Payments may be accepted in the future as reimbursement for development costs (and toner!), but not before we achieve 100% layout accuracy (enough for cutting and drilling templates) and at least 75% the speed of the Canon drivers. |
I've switched to box86 for x86 emulation, it's about 4 times faster than qemu, so it's now 6-7 seconds per page on original driver. I've dropped my encoder implementation (although it worked pretty fine).
I'm not offering a donation, quite the contrary: I'm willing to sponsor the development. |
Here is my converter implementation if it of any help. Comes with some comments and headers. |
I am also interested in developing a printer emulation for the Canon CAPT based printers (yes, I am awkward). It works the other way around, so interpreting the data sent to a parallel port (intended for an early Lasershot LBP-1310) and then creates a PDF of the printed page. Is anyone interested in this type of code - would be a good way of testing the printer driver too |
@RWAP LBP-1310 uses LIPS, not CAPT. LIPS is supported by GhostScript in most Linux installations. On an up-to-date GNU/Linux system with CUPS+GS, when you type On the other hand, the much smaller LBP-1210 is a CAPT device. On the topic of CAPT-to-PDF: all you will get is a PDF with a bitmap for every page, because CAPT doesn't have a page description language. Think of CAPT like fax on USB or IP. Meanwhile, a LIPS-to-PDF routine has more utility, but I don't know any tool that does such a thing. There's a Japanese document for LIPS on the LBP-1310, but I can't read! 🙈 For details, please check out this discussion on my repo: mounaiban#37 |
When are you going to implement support for SCoA printers?
The text was updated successfully, but these errors were encountered: