Skip to content
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

Support drawing compressed lines #9

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

KapitanOczywisty
Copy link

I've implemented drawing compressed lines, as they are sent from iprint. Compression has fallback when it reaches uncompressed line length (48 bytes).

@NaitLee
Copy link
Owner

NaitLee commented May 12, 2024

If you are sure it’s properly implemented, let’s merge this :) I personally don’t have a “new” device to test it.

Little suggestion: use -1 in place of null for previous in function* consecutiveBits, it looks cleaner for me lol

@KapitanOczywisty
Copy link
Author

KapitanOczywisty commented May 12, 2024

What model do you have? I'd test if your device does support this. Also I've found command to send 16 color gray-scale images, and this method uses lzo1x compression, so stay tuned.

@KapitanOczywisty
Copy link
Author

KapitanOczywisty commented Jul 26, 2024

@NaitLee I've been busy lately, but here is what I've figured out from app source code, I don't have time right now to make proper PR, but this should be pretty easy to follow:

0xCF (162 / -94) Draw grayscale

This mode allows drawing 16-color grayscale images. Each byte represents 2 pixels, which is then compressed using LZO1x algorithm. Also allows drawing multiple lines at once, this combined with the LZO compression, decreases the amount of data sent to the printer, though adds some processing overhead, especially on the printer side.

Color values: F - black, 0 - white, E through 1 - grayscale

Pixel data are packed line-by-line as follows: pixel[1] << 4 | pixel[0], pixel[3] << 4 | pixel[2], ..., then compressed using LZO1x_1 algorithm.

Payload: DATA_LENlo DATA_LENhi LZO_LENlo LZO_LENhi [LZO_DATA...]

  • DATA_LEN - Data length before compression
  • LZO_LEN - LZO compressed data length
  • LZO_DATA - Compressed data

Maximum of 4095 uncompressed bytes can be sent in a single packet, and since only complete lines are used, the effective limit is 21 lines. LZO1x limit can be calculated as: $\frac{4095\left[\texttt{byte}\right] * 2\left[\frac{\texttt{pixel}}{\texttt{byte}}\right]}{384\left[\frac{\texttt{pixel}}{\texttt{line}}\right]} = 21.328125 \left[\texttt{line}\right]$


I've used this lzo1x library: https://github.com/abraidwood/minilzo-js

Example code (written for node.js - buffers might require fixing for browser):

export async function printCompressed(buffer) {
  if (buffer.length === 0) {
    console.error("Nothing to print");
    return;
  }
  if (buffer.length % (DEF_CANVAS_WIDTH / 2) !== 0) {
    console.error("Invalid image size");
  }
  console.log("preparing");
  // await printer.feed(8);
  await printer.prepare(32, 50000);
  let bufferStart = 0;
  const slice = (DEF_CANVAS_WIDTH / 2) * 16;
  while (bufferStart < buffer.length) {
    const state = {
      inputBuffer: buffer.slice(bufferStart, (bufferStart += slice)),
      outputBuffer: null,
    };

    const compressed = lzo1x.compress(state);

    console.log(
      "compressed",
      compressed,
      "input",
      state.inputBuffer.length,
      "output buffer length",
      state.outputBuffer.length
    );

    await printer.send(
      printer.make(
        0xcf,
        new Uint8Array([
          state.inputBuffer.length & 0xff,
          (state.inputBuffer.length >> 8) & 0xff,
          state.outputBuffer.length & 0xff,
          (state.outputBuffer.length >> 8) & 0xff,
          ...state.outputBuffer,
        ])
      )
    );
  }
  console.log("finishing");
  await printer.finish(32);
  await printer.getDeviceState();
  await printer.flush();
}

Please let me know if this works for you! 😀

P.S. I've done some more tests to figure out other commands: https://github.com/KapitanOczywisty/Cat-Printer-Protocol/blob/main/README.MD

@NaitLee
Copy link
Owner

NaitLee commented Jul 29, 2024

The printer in my hand is an old model (GB02), it's said that it doesn't support compressed data.

I may ask my friend (he has MX06) to test it, but that's likely months later, or not going to happen at all.

I can't yet assure design of this program is capable of generating grayscale images by a few changes.

I'm personally busy as well, and I'm almost certain that I will no longer focus on my legacy projects (that means everything on github).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants