X-Git-Url: http://git.rot13.org/?p=Printer-Zebra.git;a=blobdiff_plain;f=ZPL2pbm.pl;h=e54e8fd2e10ea469d82d4409c881905f06574386;hp=0a3af92ae6ff6b398b9abd63cf7c16277a5d6dff;hb=974345e63fe26686eaacdcafd4af73564c6fda73;hpb=e3772c2d1d1bb0771080d771697530410f8419f9 diff --git a/ZPL2pbm.pl b/ZPL2pbm.pl index 0a3af92..e54e8fd 100755 --- a/ZPL2pbm.pl +++ b/ZPL2pbm.pl @@ -6,42 +6,70 @@ use Data::Dump qw(dump); # convert Zebra label printer ZPL to pbm image -my $file = shift @ARGV || die "usage: $0 dump.zpl > dump.pbm"; +my $command; +while() { + chomp; + my ( $cmd, $desc ) = split(/\s/,$_,2); + $command->{$cmd} = $desc; +} + +my $file = shift @ARGV || die "usage: $0 dump.zpl > dump.pbm\n"; open(my $in, '<', $file); -my $line = <$in>; + +our $line = ''; +sub slurp_line { + $line .= <$in> unless length $line > 3; +} +slurp_line; while( $line ) { - $line =~ s/[\r\n]+$//; - warn "# line ",dump($line); + $line =~ s/[\r\n]+$// && warn "## removed CR/LF\n"; + warn "# line ",dump($line),$/ if length($line) < 80 or $ENV{DEBUG}; if ( $line =~ s/~DG(\w+:)?(.+)// ) { - my ( $name, $t,$w ) = split(/,/,$2,4); + my ( $name, $total_bytes, $row_bytes ) = split(/,/,$2,4); + + warn "# ~DG$1 => [$name] $total_bytes bytes $row_bytes in row\n"; - warn "# ~DG$1 => [$name] t=$t w=$w\n"; + my $data = <$in>; - my $data; - read $in, $data, $t; + my $w = $row_bytes * 2; # hex digits - my $out; + my $out = ''; # ZPL decompress - my $repeat = 1; - foreach my $p ( 0 .. length($data) ) { + my $repeat = 0; + foreach my $p ( 0 .. length($data) - 1 ) { + + if ( length($out) == $total_bytes * 2 ) { + warn "END of bitmap\n"; + $line = substr($data,$p); + slurp_line; + last; + }; + my $c = substr($data,$p,1); + if ( $c eq ',' ) { - my $l = ( $w * 2 ) - length($out) % ( $w * 2 ); - $l = $w * 2 if $l == 0; + my $l = $w - ( length($out) % $w ); + $l = $w if $l == 0; warn "# $p ZERO-to-EOL $c [$l]\n"; $out .= "0" x $l; + } elsif ( $c eq '!' ) { + my $l = $w - ( length($out) % $w ); + $l = $w if $l == 0; + warn "# $p ONE-to-EOL $c [$l]\n"; + $out .= "F" x $l; } elsif ( $c eq ':' ) { - $out .= length($out) > $w ? substr($out,-$w*2) : "00" x $w; - warn "# $p :\n"; +# $out .= length($out) > $w ? substr($out,-$w) : "0" x $w; + $out .= substr($out,-$w); + warn "# $p repeat last line\n"; } elsif ( $c eq 'z' ) { $repeat += 400; } elsif ( $c ge 'g' && $c le 'y' ) { $repeat += 20 * ( ord($c) - ord('f') ); } elsif ( $c ge 'G' && $c le 'Y' ) { $repeat += ord($c) - ord('F'); - } elsif ( $c =~ m/[0-9A-F]/ ) { + } elsif ( $c =~ m/[0-9A-F]/i ) { if ( $repeat ) { warn "# $p $repeat $c\n"; $out .= $c x $repeat; @@ -51,9 +79,7 @@ while( $line ) { $out .= $c; } } else { - warn "ABORT: offset $p data [$c]"; - $line = $c . substr($data,$p); - last; + die "ABORT: offset $p data [$c]"; } warn "## $repeat [$c] out = ",length($out),$/; @@ -61,13 +87,198 @@ while( $line ) { my $bitmap = pack('H*', $out); warn "# graphics of ",length($data)," bytes ZPL decompressed to ",length($out)," hex and ", length($bitmap), " bytes bitmap\n"; - my $pw = $w * 8; - my $ph = int(length($bitmap) / $w); - print "P4\n$pw $ph\n", substr($bitmap,0,$ph*$w); + my $pw = $row_bytes * 8; + my $ph = int(length($bitmap) / $row_bytes); + print "P4\n$pw $ph\n", substr($bitmap,0,$ph*$row_bytes); - } elsif ( $line =~ s/^([~\^][^~\^]*)// ) { - warn "ZPL: $1\n"; + } elsif ( $line =~ s/^([~\^][^~\^\r\n]*)// ) { + my $cmd = substr($1,0,3); + if ( my $desc = $command->{$cmd} ) { + warn "ZPL: $1\t$desc\n"; + } else { + warn "UNKNOWN: ",dump($1),$/; + } + $line =~ s/^[\r\n]+// && warn "## removed CR/LF\n"; + } else { + my $unknown = $1 if $line =~ s/^(.)//; # printer seems to ignore invalid chars + warn "IGNORE: ",dump($unknown); } - $line = <$in> unless length $line > 0; + slurp_line; } + +__DATA__ +^A Scalable/Bitmapped Font +^A@ Use Font Name to Call Font +^B1 Code 11 Bar Code +^B2 Interleaved 2 of 5 Bar Code +^B3 Code 39 Bar Code +^B4 Code 49 Bar Code +^B5 Planet Code bar code +^B7 PDF417 Bar Code +^B8 EAN-8 Bar Code +^B9 UPC-E Bar Code +^BA Code 93 Bar Code +^BB CODABLOCK Bar Code +^BC Code 128 Bar Code (Subsets A, B, and C) +^BD UPS MaxiCode Bar Code +^BE EAN-13 Bar Code +^BF Micro-PDF417 Bar Code +^BI Industrial 2 of 5 Bar Codes +^BJ Standard 2 of 5 Bar Code +^BK ANSI Codabar Bar Code +^BL LOGMARS Bar Code +^BM MSI Bar Code +^BO Aztec Bar Code Parameters +^BP Plessey Bar Code +^BQ QR Code Bar Code +^BR RSS (Reduced Space Symbology) Bar Code +^BS UPC/EAN Extensions +^BT TLC39 bar code +^BU UPC-A Bar Code +^BX Data Matrix Bar Code +^BY Bar Code Field Default +^BZ POSTNET Bar Code +^CC Change Carets +~CC Change Carets +^CD Change Delimiter +~CD Change Delimiter +^CF Change Alphanumeric Default Font +^CI Change International Font +^CM Change Memory Letter Designation +^CO Cache On +^CT Change Tilde +~CT Change Tilde +^CV Code Validation +^CW Font Identifier +~DB Download Bitmap Font +~DE Download Encoding +^DF Download Format +~DG Download Graphics +~DN Abort Download Graphic +~DS Download Scalable Font +~DT Download TrueType Font +~DU Download Unbounded TrueType Font +~DY Download Graphics +~EG Erase Download Graphics +^FB Field Block +^FC Field Clock (for Real-Time Clock) +^FD Field Data +^FH Field Hexadecimal Indicator +^FM Multiple Field Origin Locations +^FN Field Number +^FO Field Origin +^FP Field Parameter +^FR Field Reverse Print +^FS Field Separator +^FT Field Typeset +^FV Field Variable +^FW Field Orientation +^FX Comment +^GB Graphic Box +^GC Graphic Circle +^GD Graphic Diagonal Line +^GE Graphic Ellipse +^GF Graphic Field +^GS Graphic Symbol +~HB Battery Status +~HD Head Temperature Information +^HF Graphic Symbol +^HG Host Graphic +^HH Configuration Label Return +~HI Host Identification +~HM Host RAM Status +~HS Host Status Return +~HU Return ZebraNet Alert Configuration +^HV Host Verification +^HW Host Directory List +^HY Upload Graphics +^HZ Display Description Information +^ID Object Delete +^IL Image Load +^IM Image Move +^IS Image Save +~JA Cancel All +^JB Initialize Flash Memory +~JB Reset Optional Memory +~JC Set Media Sensor Calibration +~JD Enable Communications Diagnostics +~JE Disable Diagnostics +~JF Set Battery Condition +~JG Graphing Sensor Calibration +^JJ Set Auxiliary Port +~JL Set Label Length +^JM Set Dots per Millimeter +~JN Head Test Fatal +~JO Head Test Non fatal +~JP Pause and Cancel Format +~JR Power On Reset +^JS Sensor Select +~JS Change Backfeed Sequence +^JT Head Test Interval +^JU Configuration Update +^JW Set Ribbon Tension +~JX Cancel Current Partially Input Format +^JZ Reprint After Error +~KB Kill Battery (Battery Discharge Mode) +^KD Select Date and Time Format (for Real Time Clock) +^KL Define Language +^KN Define Printer Name +^KP Define Password +^LH Label Home +^LL Label Length +^LR Label Reverse Print +^LS Label Shift +^LT Label Top +^MC Map Clear +^MD Media Darkness +^MF Media Feed +^ML Maximum Label Length +^MM Print Mode +^MN Media Tracking +^MP Mode Protection +^MT Media Type +^MU Set Units of Measurement +^MW Modify Head Cold Warning +~NC Network Connect +^NI Network ID Number +~NR Set All Network Printers Transparent +^NS Change Networking Settings +~NT Set Currently Connected Printer Transparent +^PF Slew Given Number of Dot Rows +^PH Slew to Home Position +~PH Slew to Home Position +^PM Printing Mirror Image of Label +^PO Print Orientation +^PP Programmable Pause +~PP Programmable Pause +^PQ Print Quantity +^PR Print Rate +~PR Applicator Reprint +~PS Print Start +^PW Print Width +~RO Reset Advanced Counter +^SC Set Serial Communications +~SD Set Darkness +^SE Select Encoding +^SF Serialization Field (with a Standard ^FD String) +^SL Set Mode and Language (for Real-Time Clock) +^SN Serialization Data +^SO Set Offset (for Real-Time Clock) +^SP Start Print +^SQ Halt ZebraNet Alert +^SR Set Printhead Resistance +^SS Set Media Sensors +^ST Set Date and Time (for Real-Time Clock) +^SX Set ZebraNet Alert +^SZ Set ZPL +~TA Tear-off Adjust Position +^TO Transfer Object +~WC Print Configuration Label +^WD Print Directory Label +^XA Start Format +^XB Suppress Backfeed +^XF Recall Format +^XG Recall Graphic +^XZ End Format +^ZZ Printer Sleep