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