repeat previous line : is now supported
[Printer-Zebra.git] / ZPL2pbm.pl
1 #!/usr/bin/perl
2 use warnings;
3 use strict;
4 use autodie;
5 use Data::Dump qw(dump);
6
7 # convert Zebra label printer ZPL to pbm image
8
9 my $command;
10 while(<DATA>) {
11         chomp;
12         my ( $cmd, $desc ) = split(/\s/,$_,2);
13         $command->{$cmd} = $desc;
14 }
15
16 my $file = shift @ARGV || die "usage: $0 dump.zpl > dump.pbm";
17
18 open(my $in, '<', $file);
19
20 our $line = '';
21 sub slurp_line {
22         $line .= <$in> unless length $line > 3;
23 }
24 slurp_line;
25
26 while( $line ) {
27         $line =~ s/[\r\n]+$// && warn "## removed CR/LF\n";
28         warn "# line ",dump($line),$/ if length($line) < 80 or $ENV{DEBUG};
29         if ( $line =~ s/~DG(\w+:)?(.+)// ) {
30                 my ( $name, $total_bytes, $row_bytes ) = split(/,/,$2,4);
31
32                 warn "# ~DG$1 => [$name] $total_bytes bytes $row_bytes in row\n";
33
34                 my $data = <$in>;
35
36                 my $w = $row_bytes * 2; # hex digits
37
38                 my $out = '';
39                 # ZPL decompress
40                 my $repeat = 0;
41                 foreach my $p ( 0 .. length($data) - 1 ) {
42
43                         if ( length($out) == $total_bytes * 2 ) {
44                                 warn "END of bitmap\n";
45                                 $line = substr($data,$p);
46                                 slurp_line;
47                                 last;
48                         };
49
50                         my $c = substr($data,$p,1);
51
52                         if ( $c eq ',' ) {
53                                 my $l = $w - ( length($out) % $w );
54                                 $l = $w if $l == 0;
55                                 warn "# $p ZERO-to-EOL $c [$l]\n";
56                                 $out .= "0" x $l;
57                         } elsif ( $c eq '!' ) {
58                                 my $l = $w - ( length($out) % $w );
59                                 $l = $w if $l == 0;
60                                 warn "# $p ONE-to-EOL $c [$l]\n";
61                                 $out .= "F" x $l;
62                         } elsif ( $c eq ':' ) {
63 #                               $out .= length($out) > $w ? substr($out,-$w) : "0" x $w;
64                                 $out .= substr($out,-$w);
65                                 warn "# $p repeat last line\n";
66                         } elsif ( $c eq 'z' ) {
67                                 $repeat += 400;
68                         } elsif ( $c ge 'g' && $c le 'y' ) {
69                                 $repeat += 20 * ( ord($c) - ord('f') );
70                         } elsif ( $c ge 'G' && $c le 'Y' ) {
71                                 $repeat += ord($c) - ord('F');
72                         } elsif ( $c =~ m/[0-9A-F]/i ) {
73                                 if ( $repeat ) {
74                                         warn "# $p $repeat $c\n";
75                                         $out .= $c x $repeat;
76                                         $repeat = 0;
77                                 } else {
78                                         warn "# $p hex $c\n";
79                                         $out .= $c;
80                                 }
81                         } else {
82                                 die "ABORT: offset $p data [$c]";
83                         }
84
85                         warn "## $repeat [$c] out = ",length($out),$/;
86                 }
87
88                 my $bitmap = pack('H*', $out);
89                 warn "# graphics of ",length($data)," bytes ZPL decompressed to ",length($out)," hex and ", length($bitmap), " bytes bitmap\n";
90                 my $pw = $row_bytes * 8;
91                 my $ph = int(length($bitmap) / $row_bytes);
92                 print "P4\n$pw $ph\n", substr($bitmap,0,$ph*$row_bytes);
93
94         } elsif ( $line =~ s/^([~\^][^~\^\r\n]*)// ) {
95                 my $cmd = substr($1,0,3);
96                 if ( my $desc = $command->{$cmd} ) {
97                         warn "ZPL: $1\t$desc\n";
98                 } else {
99                         warn "UNKNOWN: ",dump($1),$/;
100                 }
101                 $line =~ s/^[\r\n]+// && warn "## removed CR/LF\n";
102         } else {
103                 my $unknown = $1 if $line =~ s/^(.)//; # printer seems to ignore invalid chars
104                 warn "IGNORE: ",dump($unknown);
105         }
106
107         slurp_line;
108 }
109
110 __DATA__
111 ^A Scalable/Bitmapped Font
112 ^A@ Use Font Name to Call Font
113 ^B1 Code 11 Bar Code
114 ^B2 Interleaved 2 of 5 Bar Code
115 ^B3 Code 39 Bar Code
116 ^B4 Code 49 Bar Code
117 ^B5 Planet Code bar code
118 ^B7 PDF417 Bar Code
119 ^B8 EAN-8 Bar Code
120 ^B9 UPC-E Bar Code
121 ^BA Code 93 Bar Code
122 ^BB CODABLOCK Bar Code
123 ^BC Code 128 Bar Code (Subsets A, B, and C)
124 ^BD UPS MaxiCode Bar Code
125 ^BE EAN-13 Bar Code
126 ^BF Micro-PDF417 Bar Code
127 ^BI Industrial 2 of 5 Bar Codes
128 ^BJ Standard 2 of 5 Bar Code
129 ^BK ANSI Codabar Bar Code
130 ^BL LOGMARS Bar Code
131 ^BM MSI Bar Code
132 ^BO Aztec Bar Code Parameters
133 ^BP Plessey Bar Code
134 ^BQ QR Code Bar Code
135 ^BR RSS (Reduced Space Symbology) Bar Code
136 ^BS UPC/EAN Extensions
137 ^BT TLC39 bar code
138 ^BU UPC-A Bar Code
139 ^BX Data Matrix Bar Code
140 ^BY Bar Code Field Default
141 ^BZ POSTNET Bar Code
142 ^CC Change Carets
143 ~CC Change Carets
144 ^CD Change Delimiter
145 ~CD Change Delimiter
146 ^CF Change Alphanumeric Default Font
147 ^CI Change International Font
148 ^CM Change Memory Letter Designation
149 ^CO Cache On
150 ^CT Change Tilde
151 ~CT Change Tilde
152 ^CV Code Validation
153 ^CW Font Identifier
154 ~DB Download Bitmap Font
155 ~DE Download Encoding
156 ^DF Download Format
157 ~DG Download Graphics
158 ~DN Abort Download Graphic
159 ~DS Download Scalable Font
160 ~DT Download TrueType Font
161 ~DU Download Unbounded TrueType Font
162 ~DY Download Graphics
163 ~EG Erase Download Graphics
164 ^FB Field Block
165 ^FC Field Clock (for Real-Time Clock)
166 ^FD Field Data
167 ^FH Field Hexadecimal Indicator
168 ^FM Multiple Field Origin Locations
169 ^FN Field Number
170 ^FO Field Origin
171 ^FP Field Parameter
172 ^FR Field Reverse Print
173 ^FS Field Separator
174 ^FT Field Typeset
175 ^FV Field Variable
176 ^FW Field Orientation
177 ^FX Comment
178 ^GB Graphic Box
179 ^GC Graphic Circle
180 ^GD Graphic Diagonal Line
181 ^GE Graphic Ellipse
182 ^GF Graphic Field
183 ^GS Graphic Symbol
184 ~HB Battery Status
185 ~HD Head Temperature Information
186 ^HF Graphic Symbol
187 ^HG Host Graphic
188 ^HH Configuration Label Return
189 ~HI Host Identification
190 ~HM Host RAM Status
191 ~HS Host Status Return
192 ~HU Return ZebraNet Alert Configuration
193 ^HV Host Verification
194 ^HW Host Directory List
195 ^HY Upload Graphics
196 ^HZ Display Description Information
197 ^ID Object Delete
198 ^IL Image Load
199 ^IM Image Move
200 ^IS Image Save
201 ~JA Cancel All
202 ^JB Initialize Flash Memory
203 ~JB Reset Optional Memory
204 ~JC Set Media Sensor Calibration
205 ~JD Enable Communications Diagnostics
206 ~JE Disable Diagnostics
207 ~JF Set Battery Condition
208 ~JG Graphing Sensor Calibration
209 ^JJ Set Auxiliary Port
210 ~JL Set Label Length
211 ^JM Set Dots per Millimeter
212 ~JN Head Test Fatal
213 ~JO Head Test Non fatal
214 ~JP Pause and Cancel Format
215 ~JR Power On Reset
216 ^JS Sensor Select
217 ~JS Change Backfeed Sequence
218 ^JT Head Test Interval
219 ^JU Configuration Update
220 ^JW Set Ribbon Tension
221 ~JX Cancel Current Partially Input Format
222 ^JZ Reprint After Error
223 ~KB Kill Battery (Battery Discharge Mode)
224 ^KD Select Date and Time Format (for Real Time Clock)
225 ^KL Define Language
226 ^KN Define Printer Name
227 ^KP Define Password
228 ^LH Label Home
229 ^LL Label Length
230 ^LR Label Reverse Print
231 ^LS Label Shift
232 ^LT Label Top
233 ^MC Map Clear
234 ^MD Media Darkness
235 ^MF Media Feed
236 ^ML Maximum Label Length
237 ^MM Print Mode
238 ^MN Media Tracking
239 ^MP Mode Protection
240 ^MT Media Type
241 ^MU Set Units of Measurement
242 ^MW Modify Head Cold Warning
243 ~NC Network Connect
244 ^NI Network ID Number
245 ~NR Set All Network Printers Transparent
246 ^NS Change Networking Settings
247 ~NT Set Currently Connected Printer Transparent
248 ^PF Slew Given Number of Dot Rows
249 ^PH Slew to Home Position
250 ~PH Slew to Home Position
251 ^PM Printing Mirror Image of Label
252 ^PO Print Orientation
253 ^PP Programmable Pause
254 ~PP Programmable Pause
255 ^PQ Print Quantity
256 ^PR Print Rate
257 ~PR Applicator Reprint
258 ~PS Print Start
259 ^PW Print Width
260 ~RO Reset Advanced Counter
261 ^SC Set Serial Communications
262 ~SD Set Darkness
263 ^SE Select Encoding
264 ^SF Serialization Field (with a Standard ^FD String)
265 ^SL Set Mode and Language (for Real-Time Clock)
266 ^SN Serialization Data
267 ^SO Set Offset (for Real-Time Clock)
268 ^SP Start Print
269 ^SQ Halt ZebraNet Alert
270 ^SR Set Printhead Resistance
271 ^SS Set Media Sensors
272 ^ST Set Date and Time (for Real-Time Clock)
273 ^SX Set ZebraNet Alert
274 ^SZ Set ZPL
275 ~TA Tear-off Adjust Position
276 ^TO Transfer Object
277 ~WC Print Configuration Label
278 ^WD Print Directory Label
279 ^XA Start Format
280 ^XB Suppress Backfeed
281 ^XF Recall Format
282 ^XG Recall Graphic
283 ^XZ End Format
284 ^ZZ Printer Sleep