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

PDF417 max 255 characters #253

Open
Soushiro opened this issue Dec 21, 2023 · 8 comments · May be fixed by #259
Open

PDF417 max 255 characters #253

Soushiro opened this issue Dec 21, 2023 · 8 comments · May be fixed by #259

Comments

@Soushiro
Copy link

I try to print a 2d code with the following command :

impresion.Print2DCode(TwoDimensionCodeType.PDF417, documento.Ted, Size2DCode.LARGE, CorrectionLevel2DCode.PERCENT_15)

but it returns an error "string has more than 255 characters", I need to print a string of 350 characters which is the official stamp for electronic ballots in my country, I am generating the pdf stamp as an image and then I print it with:
print.PrintImage(bytesPDF, true, true) , but the quality is blurry.

I take this opportunity to thank you for the great work you do, really thank you very much.

@igorocampos
Copy link
Collaborator

Hi, that 255 char cap is hard coded, and the reason is that EPSON's manual says it can't be larger than that, see below
image

Right now there's no way of overriding that setting, but you could pull the code locally, and change it at least to see if it works for your printer.

@lukevp
Copy link
Owner

lukevp commented Jan 14, 2024

I see you mentioned something about your country's official ballots. Do they have to be PDF417? The reason I ask is if PDF417 is supposed to support larger data areas than ESCPOS currently supports then maybe we're doing something wrong.

Another possible interpretation of the above is that you can store more than 255 bytes, but you can only write 255 bytes to the symbol storage area at once, and pL/pH are used as offsets, so the true max size is then 65535. If that's the case and that's the right way to interpret this, then I think you would split your byte array on every 255 bytes, so byte 256 would be in a second call, and byte 512 would be in a third call, etc. And you would increment pH each time by one (so pL would be 0 and pH would be 0, then 1, then 2). I'm not sure if that's really how it works, but I don't know why they would have an offset based system like this if it didn't work that way though.

If you try this out and you're able to use the offset to print, then we could update the code around this QR format to take in longer bytes and auto split it and set offsets for the user (basically bake this into the code itself). That seems like a really helpful feature. We could have test coverage around this too.

Let me know if you try this and if you run into any issues.

@lukevp
Copy link
Owner

lukevp commented Jan 14, 2024

This document from Star makes it sound like the true data max size is 1024, and that you have to write it 255 bytes at a time to the buffer. This is probably why it's a buffered command as well and not an immediate print command - essentially there's a 1024 byte (1KB) staging area set aside for this. you write your data into it with multiple commands, and then you issue a print command. If the max was 255 then there probably wouldn't be a way to feed data into a buffer at all and it would print directly from the command.

Makes me wonder if this is a general thing across the other 2d code family or if it's only relevant to PDF417 because it stores more data?

PRs are very welcome so if you get this working, please consider contributing back as a PR so others can use it!

@igorocampos
Copy link
Collaborator

This document from Star makes it sound like the true data max size is 1024, and that you have to write it 255 bytes at a time to the buffer. This is probably why it's a buffered command as well and not an immediate print command - essentially there's a 1024 byte (1KB) staging area set aside for this. you write your data into it with multiple commands, and then you issue a print command. If the max was 255 then there probably wouldn't be a way to feed data into a buffer at all and it would print directly from the command.

Makes me wonder if this is a general thing across the other 2d code family or if it's only relevant to PDF417 because it stores more data?

PRs are very welcome so if you get this working, please consider contributing back as a PR so others can use it!

So you think we need to run the store command multiple times (255 chars each) and then in the end print out the barcode? It does make sense, but I would assume the printer just overwrites the stored bytes with a new command being sent... I would like someone to test it, if it works I can easily submit a PR with that change.

@lukevp
Copy link
Owner

lukevp commented Jan 17, 2024

Actually, I refreshed myself on ESCPOS notation a bit and I think this is the proper interpretation of the following image:
image

the confusing parts are the reuse of d1...dk and d in the definition, and the reuse of k in dk vs the k in the command specification.

They also define d as being between 2 and 255 (and Epson specifies as 0 to 255, which is probably more correct?), but the important point is - this is the definition of d, not the definition of k - i.e. they are saying a byte is a byte, and d can't be > 255, which is obvious because that's the max size of an 8-bit byte, so it doesn't even really need to be said but they said it anyway and confused the issue.

Similarly they declare the value of pL and pH as minimum 0 and maximum 255 in decimal, because that's the maximum value a single byte can hold. If you ignore all the a byte is a byte stuff, then I think the implementation becomes clearer:
image

  • The command must start with 0x1D 0x28 0x6B (Command Group)
  • The next 2 bytes are the data length (including a fixed overhead of 3 bytes for Sub-Command identifier)
  • The next 3 bytes are fixed as 0x31 0x50 0x30 (Sub-Command)
  • The maximum data size is 65535 minus 3

The data size (k) has a "calculated size - 3" because it is implying the above constraint that the fixed sub-command length is always included in the size length (i.e. pL + pH include the 3 bytes of the Sub-Command, they are not just the data length).

Given a data length of 629 characters as an example, this would be the calculation in pseudocode:

string data = "some ... string of 629 bytes in length"; // assume this is actually the right length
int k = data.Length;
int dataLength = k + 3; // should be 632
byte pH = dataLength / 256; // implies int division. should be 2
byte pL = dataLength % 256; // should be 120
var command = $"\x1D\x28\x6B{pL}{pH}\x31\x50\x30" + data;

the reason pL is 120 and pH is 2 is because dataLength = 629, and with the fixed sub-command, the length is 632. 2 x 256 = 512 and 512 + 120 = 632.

Hopefully that makes sense! I have a printer I can test this on if you want to do an implementation, but I don't know what valid PDF417 data looks like. I do see that it is some type of structured data, so we could potentially provide helpers on building the PDF417 headers.

Also, I'm not sure where I got 1024 as the max size, I think I misinterpreted something.

@igorocampos
Copy link
Collaborator

Hmm, that actually makes sense! Ok, I can fix it then, and probably double-check other bar codes they may have mistakenly similar caps in place.

@Soushiro
Copy link
Author

Soushiro commented Jan 17, 2024 via email

@igorocampos
Copy link
Collaborator

@lukevp, I submitted PR #259

I double checked all barcodes, there was just a couple more that had different values based on EPSON's manual, However I've also had to use STAR's manual to get GS1 Barcode limitations (not sure way, but it's not part of EPSON's manual that I have).

I also noted the library doesn't implement (0 <= m <= 6) barcodes, which seems to be a way to have unlimited length for CODABAR, ITF and CODE39, for it seeks a NUL byte (0x00) of the command to know when it ended. However, I'd suggest testing it out to see if that tracks. And that might not even be possible when dealing with regular printing (portrait), because once the barcode exceeds the printing area (paper width when portrait), printer will simply feed paper ( per "If the horizontal size exceeds printing area, the printer only feeds the paper").

image

image

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 a pull request may close this issue.

3 participants