Skip to content

Feat/gfc support#83

Merged
u8array merged 9 commits into
mainfrom
feat/gfc-support
May 21, 2026
Merged

Feat/gfc support#83
u8array merged 9 commits into
mainfrom
feat/gfc-support

Conversation

@u8array
Copy link
Copy Markdown
Owner

@u8array u8array commented May 21, 2026

No description provided.

u8array added 6 commits May 21, 2026 17:53
Enterprise-Systeme emittieren GF-Payloads üblicherweise nicht als raw
hex oder raw binary, sondern als :B64:<base64>:<crc>-Wrapper. Bisher
landeten ^GFB/^GFC unbedingt im browserLimit und ^GFA mit Wrapper im
decompressGFA-Pfad, der dort gar nicht greift.

Neue Pipeline: parseGfWrapper sniffe das :B64:/:Z64:-Format,
validiere CRC-16/CCITT-FALSE, dekodiere Base64 zu Bytes, normalisiere
zu Hex und reiche die in den bestehenden Pixel-Pfad weiter. CRC-
Mismatch wird gerendert (Zebra tolerieren das auch) aber als partial
gemeldet. :Z64: bleibt erstmal browserLimit, weil sync zlib eine
zusätzliche Dep oder einen async-Refactor bräuchte.
parseGfWrapper und seine Typen waren exportiert, ohne externe Nutzung —
zusätzliche API-Surface ohne Grund. Außerdem das viermal duplizierte
'^GF${rest.slice(0, 80)}…' in eine lokale Konstante gehoben.
Z64 ist real-world die Standard-Form für komprimierte ZPL-Grafiken
aus Enterprise-Systemen (SAP/Oracle/etc.); B64 alleine reicht für
hochauflösende Logos nicht, weil dann doch Base64 von rohen
Bitmap-Bytes übrigbleibt. fflate.unzlibSync deckt sync inflate
ohne async-Refactor ab (MIT, ~13 KB gzip).

Magic numbers an einer Stelle benannt: CRC16_CCITT_POLY, CRC16_MASK,
CRC_HEX_DIGITS, IMPORT_FINDING_PAYLOAD_LIMIT. Polynomial und
Maskenwerte sind CRC-Standardkonstanten und bleiben hex; nur die
Namensvergabe verschiebt die Bedeutung von 'magic' nach 'spec'.
GF-Handler war 100 Zeilen mit vier Abstraction-Levels in einem Block:
Command-Tokenparsing, Payload-Normalisierung (B64/Z64/RLE/bail),
Pixel-Painting, Cache-Anbindung. gfPayloadToHex isoliert die zweite
Stufe als pures Helper-Pair (parseGfWrapper + Inflate) und nimmt aus
dem Handler die ganze if-Treppe raus.
Zwei mutable Patterns ersetzt: 'let bytes; if (z64) bytes = inflate(…)'
und 'let bytes; try { bytes = decodeBase64() }' werden zu 'const bytes ='
Ausdrücken über tryInflateZlib bzw. base64ToBytes. Die try/catches sind
in die Helpers gewandert, sodass die Aufrufer als reine Datenflüsse
lesen.
Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces support for :B64: and :Z64: (zlib-compressed) wrappers in ZPL ^GF graphic commands, utilizing the fflate library for decompression. It adds CRC-16/CCITT-FALSE validation and updates the parser to handle ^GFB and ^GFC formats alongside existing RLE-hex data. Review feedback focuses on significant performance optimizations for large graphic payloads, specifically recommending a refactor to use Uint8Array directly to avoid redundant hex-to-string conversions. Other suggestions include replacing greedy regular expressions with more efficient string splitting and ensuring robustness against trailing whitespace in ZPL commands.

Comment thread src/lib/zplParser.ts Outdated
Comment thread src/lib/zplParser.ts
Comment thread src/lib/zplParser.ts
Comment thread src/lib/zplParser.ts
Comment thread src/lib/zplParser.ts Outdated
Comment thread src/lib/zplParser.ts Outdated
Comment thread src/lib/zplParser.ts Outdated
Comment thread src/lib/zplParser.ts Outdated
- parseGfWrapper.trim() vor dem Regex-Match — Tokenizer behält trailing
  \n auf rest, ohne trim hätte das Pattern jedes real-world Label
  mit Zeilenumbrüchen verfehlt. Neuer Test deckt das ab.
- gfPayloadToHex → gfPayloadToBytes: Uint8Array statt Hex-String durch-
  reichen spart 30k+ String-Slice + parseInt-Calls in der Paint-Loop
  bei mittelgroßen Logos. bytesToHex weg; gfaHexToBytes als Brücke
  für den decompressGFA-Pfad.
- _gfaCache erhält den originalen Format-Buchstaben (A/B/C). War
  hardcoded auf 'A'; mit B/C-Support hätte ein ^GFC,:Z64:… als
  ^GFA,:Z64:… re-exportiert, was Zebra/Labelary ablehnen.
- Veralteten Kommentar zu :Z64:-Support entfernt (ist seit fflate aktiv).
@u8array
Copy link
Copy Markdown
Owner Author

u8array commented May 21, 2026

/gemini review

Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces support for :B64: and :Z64: (zlib-compressed) wrappers within ZPL ^GF (Graphic Field) commands by adding the fflate dependency. The parser is refactored to handle ^GFA, ^GFB, and ^GFC formats, normalizing payloads into byte arrays for more efficient rendering. Review feedback identifies a critical correction for the CRC-16/CCITT-FALSE initial value (which should be 0xFFFF), suggests allowing and stripping whitespace in base64 payloads to accommodate common ZPL formatting, and recommends performance optimizations for hex-to-byte conversion.

Comment thread src/lib/zplParser.ts
Comment thread src/lib/zplParser.ts
Comment thread src/lib/zplParser.ts Outdated
Comment thread src/lib/zplParser.ts
Comment thread src/lib/zplParser.ts Outdated
Comment thread src/lib/zplParser.test.ts
…espace, faster hex decode

- CRC ist CRC-16/XMODEM (init=0), nicht CCITT-FALSE (init=0xFFFF). Mein
  vorheriger Kommentar war fehlbenannt — Gemini ist auf die Bezeichnung
  reingefallen und hat init=0xFFFF empfohlen. Empirisch via Labelary
  bestätigt: XMODEM-CRC wird akzeptiert, CCITT-FALSE abgelehnt.
  Umbenannt zu crc16Xmodem.
- GF_WRAPPER_RE erlaubt jetzt \s im base64-Anteil; parseGfWrapper stripped
  Whitespace vor atob/CRC. Real-world ZPL bricht große Payloads auf
  ~80 Char/Zeile um. Neuer Test deckt das ab.
- gfaHexToBytes nutzt jetzt Index-Zugriff + Nibble-Shift statt parseInt
  über Slices — wegen `noUncheckedIndexedAccess` mit ?? '0'-Fallback.
- Veralteten Kommentar zu :Z64:-Limit aus dem GF-Handler entfernt.
@u8array
Copy link
Copy Markdown
Owner Author

u8array commented May 21, 2026

/gemini review

Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces support for :B64: and :Z64: wrapped payloads in ZPL ^GF commands, integrating the fflate library for zlib decompression and implementing CRC-16/XMODEM validation. The ^GF command handler was refactored to support formats A, B, and C while optimizing hex-to-bytes conversion. Reviewers identified performance bottlenecks in the bit-by-bit CRC calculation and the hex parsing logic for large bitmaps, suggesting table-based implementations. Additionally, feedback was provided to preserve original command parameters in the internal cache to maintain round-trip stability for compressed data.

Comment thread src/lib/zplParser.ts
Comment thread src/lib/zplParser.ts
Comment thread src/lib/zplParser.ts Outdated
…ming

- _gfaCache übernimmt totalBytes/dataBytes aus den Original-Params statt
  beide auf gfBytes.length zu setzen. Bei :Z64: sind die zwei Werte
  unterschiedlich (uncompressed vs. on-wire), und die Firmware nutzt den
  zweiten für die Buffer-Allocation beim Re-Import.
- crc16Xmodem-JSDoc neben die Funktion gezogen (saß deplatziert vor
  einer Konstante).
- parseGfWrapper-JSDoc sagte noch 'CRC-16/CCITT-FALSE' — das war genau
  der Stolperdraht, der Geminis fehlerhafte HIGH-Suggestion ausgelöst
  hat. Auf XMODEM korrigiert.
- CRC16_CCITT_POLY → CRC16_POLY: das Polynom 0x1021 gehört zu mehreren
  CRC-Varianten; kontextfreier Name verhindert die nächste Verwirrung.

Andere Gemini-Findings aus dieser Runde übersprungen: die meisten
zitieren altes Code-Snippets (Stale-Cache im Review-Bot), das
HIGH-Finding zur CRC-init wurde empirisch via Labelary widerlegt
(XMODEM-CRC akzeptiert, CCITT-FALSE abgelehnt), LUT-Optimierungen
ohne Messung als Beleg sind spekulativ.
@u8array u8array merged commit 07284cf into main May 21, 2026
2 checks passed
@u8array u8array deleted the feat/gfc-support branch May 21, 2026 19:13
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.

1 participant