35 public function output_image($format, $symbology, $data, $options) {
36 switch (strtolower(preg_replace(
'/[^A-Za-z0-9]/',
'', $format))) {
38 header(
'Content-Type: image/png');
39 $image = $this->
render_image($symbology, $data, $options);
44 header(
'Content-Type: image/gif');
45 $image = $this->
render_image($symbology, $data, $options);
49 case 'jpg':
case 'jpe':
case 'jpeg':
50 header(
'Content-Type: image/jpeg');
51 $image = $this->
render_image($symbology, $data, $options);
56 header(
'Content-Type: image/svg+xml');
57 echo $this->
render_svg($symbology, $data, $options);
63 list($code, $widths, $width, $height, $x, $y, $w, $h) =
64 $this->encode_and_calculate_size($symbology, $data, $options);
65 $image = imagecreatetruecolor($width, $height);
66 imagesavealpha($image,
true);
67 $bgcolor = (isset($options[
'bc']) ? $options[
'bc'] :
'FFF');
68 $bgcolor = $this->allocate_color($image, $bgcolor);
69 imagefill($image, 0, 0, $bgcolor);
71 (isset($options[
'cs']) ? $options[
'cs'] :
''),
72 (isset($options[
'cm']) ? $options[
'cm'] :
'000'),
73 (isset($options[
'c2']) ? $options[
'c2'] :
'F00'),
74 (isset($options[
'c3']) ? $options[
'c3'] :
'FF0'),
75 (isset($options[
'c4']) ? $options[
'c4'] :
'0F0'),
76 (isset($options[
'c5']) ? $options[
'c5'] :
'0FF'),
77 (isset($options[
'c6']) ? $options[
'c6'] :
'00F'),
78 (isset($options[
'c7']) ? $options[
'c7'] :
'F0F'),
79 (isset($options[
'c8']) ? $options[
'c8'] :
'FFF'),
80 (isset($options[
'c9']) ? $options[
'c9'] :
'000'),
82 foreach ($colors as $i => $color) {
83 $colors[$i] = $this->allocate_color($image, $color);
85 $this->dispatch_render_image(
86 $image, $code, $x, $y, $w, $h, $colors, $widths, $options
91 public function render_svg($symbology, $data, $options) {
92 list($code, $widths, $width, $height, $x, $y, $w, $h) =
93 $this->encode_and_calculate_size($symbology, $data, $options);
94 $svg =
'<?xml version="1.0"?>';
95 $svg .=
'<svg xmlns="http://www.w3.org/2000/svg" version="1.1"';
96 $svg .=
' width="' . $width .
'" height="' . $height .
'"';
97 $svg .=
' viewBox="0 0 ' . $width .
' ' . $height .
'"><g>';
98 $bgcolor = (isset($options[
'bc']) ? $options[
'bc'] :
'white');
100 $svg .=
'<rect x="0" y="0"';
101 $svg .=
' width="' . $width .
'" height="' . $height .
'"';
102 $svg .=
' fill="' . htmlspecialchars($bgcolor) .
'"/>';
105 (isset($options[
'cs']) ? $options[
'cs'] :
''),
106 (isset($options[
'cm']) ? $options[
'cm'] :
'black'),
107 (isset($options[
'c2']) ? $options[
'c2'] :
'#FF0000'),
108 (isset($options[
'c3']) ? $options[
'c3'] :
'#FFFF00'),
109 (isset($options[
'c4']) ? $options[
'c4'] :
'#00FF00'),
110 (isset($options[
'c5']) ? $options[
'c5'] :
'#00FFFF'),
111 (isset($options[
'c6']) ? $options[
'c6'] :
'#0000FF'),
112 (isset($options[
'c7']) ? $options[
'c7'] :
'#FF00FF'),
113 (isset($options[
'c8']) ? $options[
'c8'] :
'white'),
114 (isset($options[
'c9']) ? $options[
'c9'] :
'black'),
116 $svg .= $this->dispatch_render_svg(
117 $code, $x, $y, $w, $h, $colors, $widths, $options
119 $svg .=
'</g></svg>';
125 private function encode_and_calculate_size($symbology, $data, $options) {
126 $code = $this->dispatch_encode($symbology, $data, $options);
128 (isset($options[
'wq']) ? (
int)$options[
'wq'] : 1),
129 (isset($options[
'wm']) ? (int)$options[
'wm'] : 1),
130 (isset($options[
'ww']) ? (int)$options[
'ww'] : 3),
131 (isset($options[
'wn']) ? (int)$options[
'wn'] : 1),
132 (isset($options[
'w4']) ? (int)$options[
'w4'] : 1),
133 (isset($options[
'w5']) ? (int)$options[
'w5'] : 1),
134 (isset($options[
'w6']) ? (int)$options[
'w6'] : 1),
135 (isset($options[
'w7']) ? (int)$options[
'w7'] : 1),
136 (isset($options[
'w8']) ? (int)$options[
'w8'] : 1),
137 (isset($options[
'w9']) ? (int)$options[
'w9'] : 1),
139 $size = $this->dispatch_calculate_size($code, $widths, $options);
140 $dscale = ($code && isset($code[
'g']) && $code[
'g'] ==
'm') ? 4 : 1;
141 $scale = (isset($options[
'sf']) ? (float)$options[
'sf'] : $dscale);
142 $scalex = (isset($options[
'sx']) ? (float)$options[
'sx'] : $scale);
143 $scaley = (isset($options[
'sy']) ? (float)$options[
'sy'] : $scale);
144 $dpadding = ($code && isset($code[
'g']) && $code[
'g'] ==
'm') ? 0 : 10;
145 $padding = (isset($options[
'p']) ? (int)$options[
'p'] : $dpadding);
146 $vert = (isset($options[
'pv']) ? (int)$options[
'pv'] : $padding);
147 $horiz = (isset($options[
'ph']) ? (int)$options[
'ph'] : $padding);
148 $top = (isset($options[
'pt']) ? (int)$options[
'pt'] : $vert);
149 $left = (isset($options[
'pl']) ? (int)$options[
'pl'] : $horiz);
150 $right = (isset($options[
'pr']) ? (int)$options[
'pr'] : $horiz);
151 $bottom = (isset($options[
'pb']) ? (int)$options[
'pb'] : $vert);
152 $dwidth = ceil($size[0] * $scalex) + $left + $right;
153 $dheight = ceil($size[1] * $scaley) + $top + $bottom;
154 $iwidth = (isset($options[
'w']) ? (int)$options[
'w'] : $dwidth);
155 $iheight = (isset($options[
'h']) ? (int)$options[
'h'] : $dheight);
156 $swidth = $iwidth - $left - $right;
157 $sheight = $iheight - $top - $bottom;
159 $code, $widths, $iwidth, $iheight,
160 $left, $top, $swidth, $sheight
164 private function allocate_color($image, $color) {
165 $color = preg_replace(
'/[^0-9A-Fa-f]/',
'', $color);
166 switch (strlen($color)) {
168 $v = hexdec($color) * 17;
169 return imagecolorallocate($image, $v, $v, $v);
172 return imagecolorallocate($image, $v, $v, $v);
174 $r = hexdec(substr($color, 0, 1)) * 17;
175 $g = hexdec(substr($color, 1, 1)) * 17;
176 $b = hexdec(substr($color, 2, 1)) * 17;
177 return imagecolorallocate($image, $r, $g, $b);
179 $a = hexdec(substr($color, 0, 1)) * 17;
180 $r = hexdec(substr($color, 1, 1)) * 17;
181 $g = hexdec(substr($color, 2, 1)) * 17;
182 $b = hexdec(substr($color, 3, 1)) * 17;
183 $a = round((255 - $a) * 127 / 255);
184 return imagecolorallocatealpha($image, $r, $g, $b, $a);
186 $r = hexdec(substr($color, 0, 2));
187 $g = hexdec(substr($color, 2, 2));
188 $b = hexdec(substr($color, 4, 2));
189 return imagecolorallocate($image, $r, $g, $b);
191 $a = hexdec(substr($color, 0, 2));
192 $r = hexdec(substr($color, 2, 2));
193 $g = hexdec(substr($color, 4, 2));
194 $b = hexdec(substr($color, 6, 2));
195 $a = round((255 - $a) * 127 / 255);
196 return imagecolorallocatealpha($image, $r, $g, $b, $a);
198 return imagecolorallocatealpha($image, 0, 0, 0, 127);
204 private function dispatch_encode($symbology, $data, $options) {
205 switch (strtolower(preg_replace(
'/[^A-Za-z0-9]/',
'', $symbology))) {
206 case 'upca' :
return $this->upc_a_encode($data);
207 case 'upce' :
return $this->upc_e_encode($data);
208 case 'ean13nopad' :
return $this->ean_13_encode($data,
' ');
209 case 'ean13pad' :
return $this->ean_13_encode($data,
'>');
210 case 'ean13' :
return $this->ean_13_encode($data,
'>');
211 case 'ean8' :
return $this->ean_8_encode($data);
212 case 'code39' :
return $this->code_39_encode($data);
213 case 'code39ascii':
return $this->code_39_ascii_encode($data);
214 case 'code93' :
return $this->code_93_encode($data);
215 case 'code93ascii':
return $this->code_93_ascii_encode($data);
216 case 'code128' :
return $this->code_128_encode($data, 0,
false);
217 case 'code128a' :
return $this->code_128_encode($data, 1,
false);
218 case 'code128b' :
return $this->code_128_encode($data, 2,
false);
219 case 'code128c' :
return $this->code_128_encode($data, 3,
false);
220 case 'code128ac' :
return $this->code_128_encode($data,-1,
false);
221 case 'code128bc' :
return $this->code_128_encode($data,-2,
false);
222 case 'ean128' :
return $this->code_128_encode($data, 0,
true);
223 case 'ean128a' :
return $this->code_128_encode($data, 1,
true);
224 case 'ean128b' :
return $this->code_128_encode($data, 2,
true);
225 case 'ean128c' :
return $this->code_128_encode($data, 3,
true);
226 case 'ean128ac' :
return $this->code_128_encode($data,-1,
true);
227 case 'ean128bc' :
return $this->code_128_encode($data,-2,
true);
228 case 'codabar' :
return $this->codabar_encode($data);
229 case 'itf' :
return $this->itf_encode($data);
230 case 'itf14' :
return $this->itf_encode($data);
231 case 'qr' :
return $this->qr_encode($data, 0);
232 case 'qrl' :
return $this->qr_encode($data, 0);
233 case 'qrm' :
return $this->qr_encode($data, 1);
234 case 'qrq' :
return $this->qr_encode($data, 2);
235 case 'qrh' :
return $this->qr_encode($data, 3);
236 case 'dmtx' :
return $this->dmtx_encode($data,
false,
false);
237 case 'dmtxs' :
return $this->dmtx_encode($data,
false,
false);
238 case 'dmtxr' :
return $this->dmtx_encode($data,
true,
false);
239 case 'gs1dmtx' :
return $this->dmtx_encode($data,
false,
true);
240 case 'gs1dmtxs' :
return $this->dmtx_encode($data,
false,
true);
241 case 'gs1dmtxr' :
return $this->dmtx_encode($data,
true,
true);
246 private function dispatch_calculate_size($code, $widths, $options) {
247 if ($code && isset($code[
'g']) && $code[
'g']) {
248 switch ($code[
'g']) {
250 return $this->linear_calculate_size($code, $widths);
252 return $this->matrix_calculate_size($code, $widths);
258 private function dispatch_render_image(
259 $image, $code, $x, $y, $w, $h, $colors, $widths, $options
261 if ($code && isset($code[
'g']) && $code[
'g']) {
262 switch ($code[
'g']) {
264 $this->linear_render_image(
265 $image, $code, $x, $y, $w, $h,
266 $colors, $widths, $options
270 $this->matrix_render_image(
271 $image, $code, $x, $y, $w, $h,
272 $colors, $widths, $options
279 private function dispatch_render_svg(
280 $code, $x, $y, $w, $h, $colors, $widths, $options
282 if ($code && isset($code[
'g']) && $code[
'g']) {
283 switch ($code[
'g']) {
285 return $this->linear_render_svg(
286 $code, $x, $y, $w, $h,
287 $colors, $widths, $options
290 return $this->matrix_render_svg(
291 $code, $x, $y, $w, $h,
292 $colors, $widths, $options
301 private function linear_calculate_size($code, $widths) {
303 foreach ($code[
'b'] as $block) {
304 foreach ($block[
'm'] as $module) {
305 $width += $module[1] * $widths[$module[2]];
308 return array($width, 80);
311 private function linear_render_image(
312 $image, $code, $x, $y, $w, $h, $colors, $widths, $options
314 $textheight = (isset($options[
'th']) ? (int)$options[
'th'] : 10);
315 $textsize = (isset($options[
'ts']) ? (int)$options[
'ts'] : 1);
316 $textcolor = (isset($options[
'tc']) ? $options[
'tc'] :
'000');
317 $textcolor = $this->allocate_color($image, $textcolor);
319 foreach ($code[
'b'] as $block) {
320 foreach ($block[
'm'] as $module) {
321 $width += $module[1] * $widths[$module[2]];
326 $scale = (($scale > 1) ? floor($scale) : 1);
327 $x = floor($x + ($w - $width * $scale) / 2);
330 $x = floor($x + $w / 2);
332 foreach ($code[
'b'] as $block) {
333 if (isset($block[
'l'])) {
334 $label = $block[
'l'][0];
335 $ly = (isset($block[
'l'][1]) ? (float)$block[
'l'][1] : 1);
336 $lx = (isset($block[
'l'][2]) ? (float)$block[
'l'][2] : 0.5);
337 $my = round($y + min($h, $h + ($ly - 1) * $textheight));
338 $ly = ($y + $h + $ly * $textheight);
339 $ly = round($ly - imagefontheight($textsize));
345 foreach ($block[
'm'] as $module) {
346 $mc = $colors[$module[0]];
347 $mw = $mx + $module[1] * $widths[$module[2]] * $scale;
348 imagefilledrectangle($image, $mx, $y, $mw - 1, $my - 1, $mc);
351 if (!is_null($label)) {
352 $lx = ($x + ($mx - $x) * $lx);
353 $lw = imagefontwidth($textsize) * strlen($label);
354 $lx = round($lx - $lw / 2);
355 imagestring($image, $textsize, $lx, $ly, $label, $textcolor);
361 private function linear_render_svg(
362 $code, $x, $y, $w, $h, $colors, $widths, $options
364 $textheight = (isset($options[
'th']) ? (int)$options[
'th'] : 10);
365 $textfont = (isset($options[
'tf']) ? $options[
'tf'] :
'monospace');
366 $textsize = (isset($options[
'ts']) ? (int)$options[
'ts'] : 10);
367 $textcolor = (isset($options[
'tc']) ? $options[
'tc'] :
'black');
369 foreach ($code[
'b'] as $block) {
370 foreach ($block[
'm'] as $module) {
371 $width += $module[1] * $widths[$module[2]];
377 $scale = floor($scale);
378 $x = floor($x + ($w - $width * $scale) / 2);
382 $x = floor($x + $w / 2);
384 $tx =
'translate(' . $x .
' ' . $y .
')';
385 if ($scale != 1) $tx .=
' scale(' . $scale .
' 1)';
386 $svg =
'<g transform="' . htmlspecialchars($tx) .
'">';
388 foreach ($code[
'b'] as $block) {
389 if (isset($block[
'l'])) {
390 $label = $block[
'l'][0];
391 $ly = (isset($block[
'l'][1]) ? (float)$block[
'l'][1] : 1);
392 $lx = (isset($block[
'l'][2]) ? (float)$block[
'l'][2] : 0.5);
393 $mh = min($h, $h + ($ly - 1) * $textheight);
394 $ly = $h + $ly * $textheight;
401 foreach ($block[
'm'] as $module) {
402 $mc = htmlspecialchars($colors[$module[0]]);
403 $mw = $module[1] * $widths[$module[2]];
406 $svg .=
' x="' . $mx .
'" y="0"';
407 $svg .=
' width="' . $mw .
'"';
408 $svg .=
' height="' . $mh .
'"';
409 $svg .=
' fill="' . $mc .
'"/>';
413 if (!is_null($label)) {
414 $lx = ($x + ($mx - $x) * $lx);
416 $svg .=
' x="' . $lx .
'" y="' . $ly .
'"';
417 $svg .=
' text-anchor="middle"';
418 $svg .=
' font-family="'.htmlspecialchars($textfont).
'"';
419 $svg .=
' font-size="'.htmlspecialchars($textsize).
'"';
420 $svg .=
' fill="'.htmlspecialchars($textcolor).
'">';
421 $svg .= htmlspecialchars($label);
427 return $svg .
'</g>';
432 private function matrix_calculate_size($code, $widths) {
434 $code[
'q'][3] * $widths[0] +
435 $code[
's'][0] * $widths[1] +
436 $code[
'q'][1] * $widths[0]
439 $code[
'q'][0] * $widths[0] +
440 $code[
's'][1] * $widths[1] +
441 $code[
'q'][2] * $widths[0]
443 return array($width, $height);
446 private function matrix_render_image(
447 $image, $code, $x, $y, $w, $h, $colors, $widths, $options
449 $shape = (isset($options[
'ms']) ? strtolower($options[
'ms']) :
'');
450 $density = (isset($options[
'md']) ? (float)$options[
'md'] : 1);
451 list($width, $height) = $this->matrix_calculate_size($code, $widths);
452 if ($width && $height) {
453 $scale = min($w / $width, $h / $height);
454 $scale = (($scale > 1) ? floor($scale) : 1);
455 $x = floor($x + ($w - $width * $scale) / 2);
456 $y = floor($y + ($h - $height * $scale) / 2);
459 $x = floor($x + $w / 2);
460 $y = floor($y + $h / 2);
462 $x += $code[
'q'][3] * $widths[0] * $scale;
463 $y += $code[
'q'][0] * $widths[0] * $scale;
464 $wh = $widths[1] * $scale;
465 foreach ($code[
'b'] as $by => $row) {
466 $y1 = $y + $by * $wh;
467 foreach ($row as $bx => $color) {
468 $x1 = $x + $bx * $wh;
469 $mc = $colors[$color];
470 $this->matrix_dot_image(
471 $image, $x1, $y1, $wh, $wh, $mc, $shape, $density
477 private function matrix_render_svg(
478 $code, $x, $y, $w, $h, $colors, $widths, $options
480 $shape = (isset($options[
'ms']) ? strtolower($options[
'ms']) :
'');
481 $density = (isset($options[
'md']) ? (float)$options[
'md'] : 1);
482 list($width, $height) = $this->matrix_calculate_size($code, $widths);
483 if ($width && $height) {
484 $scale = min($w / $width, $h / $height);
485 if ($scale > 1) $scale = floor($scale);
486 $x = floor($x + ($w - $width * $scale) / 2);
487 $y = floor($y + ($h - $height * $scale) / 2);
490 $x = floor($x + $w / 2);
491 $y = floor($y + $h / 2);
493 $tx =
'translate(' . $x .
' ' . $y .
')';
494 if ($scale != 1) $tx .=
' scale(' . $scale .
' ' . $scale .
')';
495 $svg =
'<g transform="' . htmlspecialchars($tx) .
'">';
496 $x = $code[
'q'][3] * $widths[0];
497 $y = $code[
'q'][0] * $widths[0];
499 foreach ($code[
'b'] as $by => $row) {
500 $y1 = $y + $by * $wh;
501 foreach ($row as $bx => $color) {
502 $x1 = $x + $bx * $wh;
503 $mc = $colors[$color];
505 $svg .= $this->matrix_dot_svg(
506 $x1, $y1, $wh, $wh, $mc, $shape, $density
511 return $svg .
'</g>';
514 private function matrix_dot_image($image, $x, $y, $w, $h, $mc, $ms, $md) {
517 $x = floor($x + (1 - $md) * $w / 2);
518 $y = floor($y + (1 - $md) * $h / 2);
521 imagefilledrectangle($image, $x, $y, $x+$w-1, $y+$h-1, $mc);
524 $cx = floor($x + $w / 2);
525 $cy = floor($y + $h / 2);
526 $dx = ceil($w * $md);
527 $dy = ceil($h * $md);
528 imagefilledellipse($image, $cx, $cy, $dx, $dy, $mc);
531 $x = floor($x + (1 - $md) * $w / 2);
532 $y = floor($y + (1 - $md) * $h / 2);
535 imageline($image, $x, $y, $x+$w-1, $y+$h-1, $mc);
536 imageline($image, $x, $y+$h-1, $x+$w-1, $y, $mc);
541 private function matrix_dot_svg($x, $y, $w, $h, $mc, $ms, $md) {
544 $x += (1 - $md) * $w / 2;
545 $y += (1 - $md) * $h / 2;
548 $svg =
'<rect x="' . $x .
'" y="' . $y .
'"';
549 $svg .=
' width="' . $w .
'" height="' . $h .
'"';
550 $svg .=
' fill="' . $mc .
'"/>';
557 $svg =
'<ellipse cx="' . $cx .
'" cy="' . $cy .
'"';
558 $svg .=
' rx="' . $rx .
'" ry="' . $ry .
'"';
559 $svg .=
' fill="' . $mc .
'"/>';
562 $x1 = $x + (1 - $md) * $w / 2;
563 $y1 = $y + (1 - $md) * $h / 2;
564 $x2 = $x + $w - (1 - $md) * $w / 2;
565 $y2 = $y + $h - (1 - $md) * $h / 2;
566 $svg =
'<line x1="' . $x1 .
'" y1="' . $y1 .
'"';
567 $svg .=
' x2="' . $x2 .
'" y2="' . $y2 .
'"';
568 $svg .=
' stroke="' . $mc .
'"';
569 $svg .=
' stroke-width="' . ($md / 5) .
'"/>';
570 $svg .=
'<line x1="' . $x1 .
'" y1="' . $y2 .
'"';
571 $svg .=
' x2="' . $x2 .
'" y2="' . $y1 .
'"';
572 $svg .=
' stroke="' . $mc .
'"';
573 $svg .=
' stroke-width="' . ($md / 5) .
'"/>';
574 return '<g>' . $svg .
'</g>';
580 private function upc_a_encode($data) {
581 $data = $this->upc_a_normalize($data);
584 $digit = substr($data, 0, 1);
586 'm' => array(array(0, 9, 0)),
587 'l' => array($digit, 0, 1/3)
598 array(0, $this->upc_alphabet[$digit][0], 1),
599 array(1, $this->upc_alphabet[$digit][1], 1),
600 array(0, $this->upc_alphabet[$digit][2], 1),
601 array(1, $this->upc_alphabet[$digit][3], 1),
605 for ($i = 1; $i < 6; $i++) {
606 $digit = substr($data, $i, 1);
609 array(0, $this->upc_alphabet[$digit][0], 1),
610 array(1, $this->upc_alphabet[$digit][1], 1),
611 array(0, $this->upc_alphabet[$digit][2], 1),
612 array(1, $this->upc_alphabet[$digit][3], 1),
614 'l' => array($digit, 0.5, (6 - $i) / 6)
628 for ($i = 6; $i < 11; $i++) {
629 $digit = substr($data, $i, 1);
632 array(1, $this->upc_alphabet[$digit][0], 1),
633 array(0, $this->upc_alphabet[$digit][1], 1),
634 array(1, $this->upc_alphabet[$digit][2], 1),
635 array(0, $this->upc_alphabet[$digit][3], 1),
637 'l' => array($digit, 0.5, (11 - $i) / 6)
641 $digit = substr($data, 11, 1);
644 array(1, $this->upc_alphabet[$digit][0], 1),
645 array(0, $this->upc_alphabet[$digit][1], 1),
646 array(1, $this->upc_alphabet[$digit][2], 1),
647 array(0, $this->upc_alphabet[$digit][3], 1),
658 'm' => array(array(0, 9, 0)),
659 'l' => array($digit, 0, 2/3)
662 return array(
'g' =>
'l',
'b' => $blocks);
665 private function upc_e_encode($data) {
666 $data = $this->upc_e_normalize($data);
670 'm' => array(array(0, 9, 0))
680 $system = substr($data, 0, 1) & 1;
681 $check = substr($data, 7, 1);
682 $pbits = $this->upc_parity[$check];
683 for ($i = 1; $i < 7; $i++) {
684 $digit = substr($data, $i, 1);
685 $pbit = $pbits[$i - 1] ^ $system;
688 array(0, $this->upc_alphabet[$digit][$pbit ? 3 : 0], 1),
689 array(1, $this->upc_alphabet[$digit][$pbit ? 2 : 1], 1),
690 array(0, $this->upc_alphabet[$digit][$pbit ? 1 : 2], 1),
691 array(1, $this->upc_alphabet[$digit][$pbit ? 0 : 3], 1),
693 'l' => array($digit, 0.5, (7 - $i) / 7)
708 'm' => array(array(0, 9, 0))
711 return array(
'g' =>
'l',
'b' => $blocks);
714 private function ean_13_encode($data, $pad) {
715 $data = $this->ean_13_normalize($data);
718 $system = substr($data, 0, 1);
721 $this->upc_parity[$system] :
722 array(1, 1, 1, 1, 1, 1)
725 'm' => array(array(0, 9, 0)),
726 'l' => array($system, 0.5, 1/3)
736 for ($i = 1; $i < 7; $i++) {
737 $digit = substr($data, $i, 1);
738 $pbit = $pbits[$i - 1];
741 array(0, $this->upc_alphabet[$digit][$pbit ? 0 : 3], 1),
742 array(1, $this->upc_alphabet[$digit][$pbit ? 1 : 2], 1),
743 array(0, $this->upc_alphabet[$digit][$pbit ? 2 : 1], 1),
744 array(1, $this->upc_alphabet[$digit][$pbit ? 3 : 0], 1),
746 'l' => array($digit, 0.5, (7 - $i) / 7)
760 for ($i = 7; $i < 13; $i++) {
761 $digit = substr($data, $i, 1);
764 array(1, $this->upc_alphabet[$digit][0], 1),
765 array(0, $this->upc_alphabet[$digit][1], 1),
766 array(1, $this->upc_alphabet[$digit][2], 1),
767 array(0, $this->upc_alphabet[$digit][3], 1),
769 'l' => array($digit, 0.5, (13 - $i) / 7)
781 'm' => array(array(0, 9, 0)),
782 'l' => array($pad, 0.5, 2/3)
785 return array(
'g' =>
'l',
'b' => $blocks);
788 private function ean_8_encode($data) {
789 $data = $this->ean_8_normalize($data);
793 'm' => array(array(0, 9, 0)),
794 'l' => array(
'<', 0.5, 1/3)
804 for ($i = 0; $i < 4; $i++) {
805 $digit = substr($data, $i, 1);
808 array(0, $this->upc_alphabet[$digit][0], 1),
809 array(1, $this->upc_alphabet[$digit][1], 1),
810 array(0, $this->upc_alphabet[$digit][2], 1),
811 array(1, $this->upc_alphabet[$digit][3], 1),
813 'l' => array($digit, 0.5, (4 - $i) / 5)
827 for ($i = 4; $i < 8; $i++) {
828 $digit = substr($data, $i, 1);
831 array(1, $this->upc_alphabet[$digit][0], 1),
832 array(0, $this->upc_alphabet[$digit][1], 1),
833 array(1, $this->upc_alphabet[$digit][2], 1),
834 array(0, $this->upc_alphabet[$digit][3], 1),
836 'l' => array($digit, 0.5, (8 - $i) / 5)
848 'm' => array(array(0, 9, 0)),
849 'l' => array(
'>', 0.5, 2/3)
852 return array(
'g' =>
'l',
'b' => $blocks);
855 private function upc_a_normalize($data) {
856 $data = preg_replace(
'/[^0-9*]/',
'', $data);
858 if (strlen($data) < 5) {
859 $data = str_repeat(
'0', 12);
860 }
else if (strlen($data) < 12) {
861 $system = substr($data, 0, 1);
862 $edata = substr($data, 1, -2);
863 $epattern = (int)substr($data, -2, 1);
864 $check = substr($data, -1);
866 $left = $system . substr($edata, 0, 2) . $epattern;
867 $right = substr($edata, 2) . $check;
868 }
else if ($epattern < strlen($edata)) {
869 $left = $system . substr($edata, 0, $epattern);
870 $right = substr($edata, $epattern) . $check;
872 $left = $system . $edata;
873 $right = $epattern . $check;
875 $center = str_repeat(
'0', 12 - strlen($left . $right));
876 $data = $left . $center . $right;
877 }
else if (strlen($data) > 12) {
878 $left = substr($data, 0, 6);
879 $right = substr($data, -6);
880 $data = $left . $right;
883 while (($o = strrpos($data,
'*')) !==
false) {
885 for ($i = 0; $i < 12; $i++) {
886 $digit = substr($data, $i, 1);
887 $checksum += (($i % 2) ? 1 : 3) * $digit;
889 $checksum *= (($o % 2) ? 9 : 3);
890 $left = substr($data, 0, $o);
891 $center = substr($checksum, -1);
892 $right = substr($data, $o + 1);
893 $data = $left . $center . $right;
898 private function upc_e_normalize($data) {
899 $data = preg_replace(
'/[^0-9*]/',
'', $data);
902 '/^([01])([0-9][0-9][0-9][0-9][0-9][0-9])([0-9])$/',
909 '/^([01])([0-9][0-9][0-9][0-9][0-9][0-9])([*])$/',
912 $data = $this->upc_a_normalize($data);
913 return $m[1] . $m[2] . substr($data, -1);
916 $data = $this->upc_a_normalize($data);
918 '/^([01])([0-9][0-9])([0-2])0000([0-9][0-9][0-9])([0-9])$/',
921 return $m[1] . $m[2] . $m[4] . $m[3] . $m[5];
924 '/^([01])([0-9][0-9][0-9])00000([0-9][0-9])([0-9])$/',
927 return $m[1] . $m[2] . $m[3] .
'3' . $m[4];
930 '/^([01])([0-9][0-9][0-9][0-9])00000([0-9])([0-9])$/',
933 return $m[1] . $m[2] . $m[3] .
'4' . $m[4];
936 '/^([01])([0-9][0-9][0-9][0-9][0-9])0000([5-9])([0-9])$/',
939 return $m[1] . $m[2] . $m[3] . $m[4];
941 return str_repeat(
'0', 8);
944 private function ean_13_normalize($data) {
945 $data = preg_replace(
'/[^0-9*]/',
'', $data);
947 if (strlen($data) < 13) {
948 return '0' . $this->upc_a_normalize($data);
949 }
else if (strlen($data) > 13) {
950 $left = substr($data, 0, 7);
951 $right = substr($data, -6);
952 $data = $left . $right;
955 while (($o = strrpos($data,
'*')) !==
false) {
957 for ($i = 0; $i < 13; $i++) {
958 $digit = (int)$data[$i];
959 $checksum += (($i % 2) ? 3 : 1) * $digit;
961 $checksum *= (($o % 2) ? 3 : 9);
962 $left = substr($data, 0, $o);
963 $center = substr($checksum, -1);
964 $right = substr($data, $o + 1);
965 $data = $left . $center . $right;
970 private function ean_8_normalize($data) {
971 $data = preg_replace(
'/[^0-9*]/',
'', $data);
973 if (strlen($data) < 8) {
974 $midpoint = floor(strlen($data) / 2);
975 $left = substr($data, 0, $midpoint);
976 $center = str_repeat(
'0', 8 - strlen($data));
977 $right = substr($data, $midpoint);
978 $data = $left . $center . $right;
979 }
else if (strlen($data) > 8) {
980 $left = substr($data, 0, 4);
981 $right = substr($data, -4);
982 $data = $left . $right;
985 while (($o = strrpos($data,
'*')) !==
false) {
987 for ($i = 0; $i < 8; $i++) {
988 $digit = substr($data, $i, 1);
989 $checksum += (($i % 2) ? 1 : 3) * $digit;
991 $checksum *= (($o % 2) ? 9 : 3);
992 $left = substr($data, 0, $o);
993 $center = substr($checksum, -1);
994 $right = substr($data, $o + 1);
995 $data = $left . $center . $right;
1000 private $upc_alphabet = array(
1001 '0' => array(3, 2, 1, 1),
1002 '1' => array(2, 2, 2, 1),
1003 '2' => array(2, 1, 2, 2),
1004 '3' => array(1, 4, 1, 1),
1005 '4' => array(1, 1, 3, 2),
1006 '5' => array(1, 2, 3, 1),
1007 '6' => array(1, 1, 1, 4),
1008 '7' => array(1, 3, 1, 2),
1009 '8' => array(1, 2, 1, 3),
1010 '9' => array(3, 1, 1, 2),
1013 private $upc_parity = array(
1014 '0' => array(1, 1, 1, 0, 0, 0),
1015 '1' => array(1, 1, 0, 1, 0, 0),
1016 '2' => array(1, 1, 0, 0, 1, 0),
1017 '3' => array(1, 1, 0, 0, 0, 1),
1018 '4' => array(1, 0, 1, 1, 0, 0),
1019 '5' => array(1, 0, 0, 1, 1, 0),
1020 '6' => array(1, 0, 0, 0, 1, 1),
1021 '7' => array(1, 0, 1, 0, 1, 0),
1022 '8' => array(1, 0, 1, 0, 0, 1),
1023 '9' => array(1, 0, 0, 1, 0, 1),
1028 private function code_39_encode($data) {
1029 $data = strtoupper(preg_replace(
'/[^0-9A-Za-z%$\/+ .-]/',
'', $data));
1034 array(1, 1, 1), array(0, 1, 2), array(1, 1, 1),
1035 array(0, 1, 1), array(1, 1, 2), array(0, 1, 1),
1036 array(1, 1, 2), array(0, 1, 1), array(1, 1, 1),
1041 for ($i = 0, $n = strlen($data); $i < $n; $i++) {
1043 'm' => array(array(0, 1, 3))
1045 $char = substr($data, $i, 1);
1046 $block = $this->code_39_alphabet[$char];
1049 array(1, 1, $block[0]),
1050 array(0, 1, $block[1]),
1051 array(1, 1, $block[2]),
1052 array(0, 1, $block[3]),
1053 array(1, 1, $block[4]),
1054 array(0, 1, $block[5]),
1055 array(1, 1, $block[6]),
1056 array(0, 1, $block[7]),
1057 array(1, 1, $block[8]),
1063 'm' => array(array(0, 1, 3))
1068 array(1, 1, 1), array(0, 1, 2), array(1, 1, 1),
1069 array(0, 1, 1), array(1, 1, 2), array(0, 1, 1),
1070 array(1, 1, 2), array(0, 1, 1), array(1, 1, 1),
1075 return array(
'g' =>
'l',
'b' => $blocks);
1078 private function code_39_ascii_encode($data) {
1081 $modules[] = array(1, 1, 1);
1082 $modules[] = array(0, 1, 2);
1083 $modules[] = array(1, 1, 1);
1084 $modules[] = array(0, 1, 1);
1085 $modules[] = array(1, 1, 2);
1086 $modules[] = array(0, 1, 1);
1087 $modules[] = array(1, 1, 2);
1088 $modules[] = array(0, 1, 1);
1089 $modules[] = array(1, 1, 1);
1092 for ($i = 0, $n = strlen($data); $i < $n; $i++) {
1093 $char = substr($data, $i, 1);
1096 if ($ch < 32 || $ch >= 127) {
1101 $ch = $this->code_39_asciibet[$ch];
1102 for ($j = 0, $m = strlen($ch); $j < $m; $j++) {
1103 $c = substr($ch, $j, 1);
1104 $b = $this->code_39_alphabet[$c];
1105 $modules[] = array(0, 1, 3);
1106 $modules[] = array(1, 1, $b[0]);
1107 $modules[] = array(0, 1, $b[1]);
1108 $modules[] = array(1, 1, $b[2]);
1109 $modules[] = array(0, 1, $b[3]);
1110 $modules[] = array(1, 1, $b[4]);
1111 $modules[] = array(0, 1, $b[5]);
1112 $modules[] = array(1, 1, $b[6]);
1113 $modules[] = array(0, 1, $b[7]);
1114 $modules[] = array(1, 1, $b[8]);
1118 $modules[] = array(0, 1, 3);
1120 $modules[] = array(1, 1, 1);
1121 $modules[] = array(0, 1, 2);
1122 $modules[] = array(1, 1, 1);
1123 $modules[] = array(0, 1, 1);
1124 $modules[] = array(1, 1, 2);
1125 $modules[] = array(0, 1, 1);
1126 $modules[] = array(1, 1, 2);
1127 $modules[] = array(0, 1, 1);
1128 $modules[] = array(1, 1, 1);
1130 $blocks = array(array(
'm' => $modules,
'l' => array($label)));
1131 return array(
'g' =>
'l',
'b' => $blocks);
1134 private function code_93_encode($data) {
1135 $data = strtoupper(preg_replace(
'/[^0-9A-Za-z%+\/$ .-]/',
'', $data));
1138 $modules[] = array(1, 1, 1);
1139 $modules[] = array(0, 1, 1);
1140 $modules[] = array(1, 1, 1);
1141 $modules[] = array(0, 1, 1);
1142 $modules[] = array(1, 4, 1);
1143 $modules[] = array(0, 1, 1);
1146 for ($i = 0, $n = strlen($data); $i < $n; $i++) {
1147 $char = substr($data, $i, 1);
1148 $block = $this->code_93_alphabet[$char];
1149 $modules[] = array(1, $block[0], 1);
1150 $modules[] = array(0, $block[1], 1);
1151 $modules[] = array(1, $block[2], 1);
1152 $modules[] = array(0, $block[3], 1);
1153 $modules[] = array(1, $block[4], 1);
1154 $modules[] = array(0, $block[5], 1);
1155 $values[] = $block[6];
1158 for ($i = 0; $i < 2; $i++) {
1159 $index = count($values);
1165 $checksum += $weight * $values[$index];
1167 $weight %= ($i ? 15 : 20);
1169 $values[] = $checksum;
1171 $alphabet = array_values($this->code_93_alphabet);
1172 for ($i = count($values) - 2, $n = count($values); $i < $n; $i++) {
1173 $block = $alphabet[$values[$i]];
1174 $modules[] = array(1, $block[0], 1);
1175 $modules[] = array(0, $block[1], 1);
1176 $modules[] = array(1, $block[2], 1);
1177 $modules[] = array(0, $block[3], 1);
1178 $modules[] = array(1, $block[4], 1);
1179 $modules[] = array(0, $block[5], 1);
1182 $modules[] = array(1, 1, 1);
1183 $modules[] = array(0, 1, 1);
1184 $modules[] = array(1, 1, 1);
1185 $modules[] = array(0, 1, 1);
1186 $modules[] = array(1, 4, 1);
1187 $modules[] = array(0, 1, 1);
1188 $modules[] = array(1, 1, 1);
1190 $blocks = array(array(
'm' => $modules,
'l' => array($data)));
1191 return array(
'g' =>
'l',
'b' => $blocks);
1194 private function code_93_ascii_encode($data) {
1197 $modules[] = array(1, 1, 1);
1198 $modules[] = array(0, 1, 1);
1199 $modules[] = array(1, 1, 1);
1200 $modules[] = array(0, 1, 1);
1201 $modules[] = array(1, 4, 1);
1202 $modules[] = array(0, 1, 1);
1206 for ($i = 0, $n = strlen($data); $i < $n; $i++) {
1207 $char = substr($data, $i, 1);
1210 if ($ch < 32 || $ch >= 127) {
1215 $ch = $this->code_93_asciibet[$ch];
1216 for ($j = 0, $m = strlen($ch); $j < $m; $j++) {
1217 $c = substr($ch, $j, 1);
1218 $b = $this->code_93_alphabet[$c];
1219 $modules[] = array(1, $b[0], 1);
1220 $modules[] = array(0, $b[1], 1);
1221 $modules[] = array(1, $b[2], 1);
1222 $modules[] = array(0, $b[3], 1);
1223 $modules[] = array(1, $b[4], 1);
1224 $modules[] = array(0, $b[5], 1);
1230 for ($i = 0; $i < 2; $i++) {
1231 $index = count($values);
1237 $checksum += $weight * $values[$index];
1239 $weight %= ($i ? 15 : 20);
1241 $values[] = $checksum;
1243 $alphabet = array_values($this->code_93_alphabet);
1244 for ($i = count($values) - 2, $n = count($values); $i < $n; $i++) {
1245 $block = $alphabet[$values[$i]];
1246 $modules[] = array(1, $block[0], 1);
1247 $modules[] = array(0, $block[1], 1);
1248 $modules[] = array(1, $block[2], 1);
1249 $modules[] = array(0, $block[3], 1);
1250 $modules[] = array(1, $block[4], 1);
1251 $modules[] = array(0, $block[5], 1);
1254 $modules[] = array(1, 1, 1);
1255 $modules[] = array(0, 1, 1);
1256 $modules[] = array(1, 1, 1);
1257 $modules[] = array(0, 1, 1);
1258 $modules[] = array(1, 4, 1);
1259 $modules[] = array(0, 1, 1);
1260 $modules[] = array(1, 1, 1);
1262 $blocks = array(array(
'm' => $modules,
'l' => array($label)));
1263 return array(
'g' =>
'l',
'b' => $blocks);
1266 private $code_39_alphabet = array(
1267 '1' => array(2, 1, 1, 2, 1, 1, 1, 1, 2),
1268 '2' => array(1, 1, 2, 2, 1, 1, 1, 1, 2),
1269 '3' => array(2, 1, 2, 2, 1, 1, 1, 1, 1),
1270 '4' => array(1, 1, 1, 2, 2, 1, 1, 1, 2),
1271 '5' => array(2, 1, 1, 2, 2, 1, 1, 1, 1),
1272 '6' => array(1, 1, 2, 2, 2, 1, 1, 1, 1),
1273 '7' => array(1, 1, 1, 2, 1, 1, 2, 1, 2),
1274 '8' => array(2, 1, 1, 2, 1, 1, 2, 1, 1),
1275 '9' => array(1, 1, 2, 2, 1, 1, 2, 1, 1),
1276 '0' => array(1, 1, 1, 2, 2, 1, 2, 1, 1),
1277 'A' => array(2, 1, 1, 1, 1, 2, 1, 1, 2),
1278 'B' => array(1, 1, 2, 1, 1, 2, 1, 1, 2),
1279 'C' => array(2, 1, 2, 1, 1, 2, 1, 1, 1),
1280 'D' => array(1, 1, 1, 1, 2, 2, 1, 1, 2),
1281 'E' => array(2, 1, 1, 1, 2, 2, 1, 1, 1),
1282 'F' => array(1, 1, 2, 1, 2, 2, 1, 1, 1),
1283 'G' => array(1, 1, 1, 1, 1, 2, 2, 1, 2),
1284 'H' => array(2, 1, 1, 1, 1, 2, 2, 1, 1),
1285 'I' => array(1, 1, 2, 1, 1, 2, 2, 1, 1),
1286 'J' => array(1, 1, 1, 1, 2, 2, 2, 1, 1),
1287 'K' => array(2, 1, 1, 1, 1, 1, 1, 2, 2),
1288 'L' => array(1, 1, 2, 1, 1, 1, 1, 2, 2),
1289 'M' => array(2, 1, 2, 1, 1, 1, 1, 2, 1),
1290 'N' => array(1, 1, 1, 1, 2, 1, 1, 2, 2),
1291 'O' => array(2, 1, 1, 1, 2, 1, 1, 2, 1),
1292 'P' => array(1, 1, 2, 1, 2, 1, 1, 2, 1),
1293 'Q' => array(1, 1, 1, 1, 1, 1, 2, 2, 2),
1294 'R' => array(2, 1, 1, 1, 1, 1, 2, 2, 1),
1295 'S' => array(1, 1, 2, 1, 1, 1, 2, 2, 1),
1296 'T' => array(1, 1, 1, 1, 2, 1, 2, 2, 1),
1297 'U' => array(2, 2, 1, 1, 1, 1, 1, 1, 2),
1298 'V' => array(1, 2, 2, 1, 1, 1, 1, 1, 2),
1299 'W' => array(2, 2, 2, 1, 1, 1, 1, 1, 1),
1300 'X' => array(1, 2, 1, 1, 2, 1, 1, 1, 2),
1301 'Y' => array(2, 2, 1, 1, 2, 1, 1, 1, 1),
1302 'Z' => array(1, 2, 2, 1, 2, 1, 1, 1, 1),
1303 '-' => array(1, 2, 1, 1, 1, 1, 2, 1, 2),
1304 '.' => array(2, 2, 1, 1, 1, 1, 2, 1, 1),
1305 ' ' => array(1, 2, 2, 1, 1, 1, 2, 1, 1),
1306 '*' => array(1, 2, 1, 1, 2, 1, 2, 1, 1),
1307 '+' => array(1, 2, 1, 1, 1, 2, 1, 2, 1),
1308 '/' => array(1, 2, 1, 2, 1, 1, 1, 2, 1),
1309 '$' => array(1, 2, 1, 2, 1, 2, 1, 1, 1),
1310 '%' => array(1, 1, 1, 2, 1, 2, 1, 2, 1),
1313 private $code_39_asciibet = array(
1314 '%U',
'$A',
'$B',
'$C',
'$D',
'$E',
'$F',
'$G',
1315 '$H',
'$I',
'$J',
'$K',
'$L',
'$M',
'$N',
'$O',
1316 '$P',
'$Q',
'$R',
'$S',
'$T',
'$U',
'$V',
'$W',
1317 '$X',
'$Y',
'$Z',
'%A',
'%B',
'%C',
'%D',
'%E',
1318 ' ' ,
'/A',
'/B',
'/C',
'/D',
'/E',
'/F',
'/G',
1319 '/H',
'/I',
'/J',
'/K',
'/L',
'-' ,
'.' ,
'/O',
1320 '0' ,
'1' ,
'2' ,
'3' ,
'4' ,
'5' ,
'6' ,
'7' ,
1321 '8' ,
'9' ,
'/Z',
'%F',
'%G',
'%H',
'%I',
'%J',
1322 '%V',
'A' ,
'B' ,
'C' ,
'D' ,
'E' ,
'F' ,
'G' ,
1323 'H' ,
'I' ,
'J' ,
'K' ,
'L' ,
'M' ,
'N' ,
'O' ,
1324 'P' ,
'Q' ,
'R' ,
'S' ,
'T' ,
'U' ,
'V' ,
'W' ,
1325 'X' ,
'Y' ,
'Z' ,
'%K',
'%L',
'%M',
'%N',
'%O',
1326 '%W',
'+A',
'+B',
'+C',
'+D',
'+E',
'+F',
'+G',
1327 '+H',
'+I',
'+J',
'+K',
'+L',
'+M',
'+N',
'+O',
1328 '+P',
'+Q',
'+R',
'+S',
'+T',
'+U',
'+V',
'+W',
1329 '+X',
'+Y',
'+Z',
'%P',
'%Q',
'%R',
'%S',
'%T',
1332 private $code_93_alphabet = array(
1333 '0' => array(1, 3, 1, 1, 1, 2, 0),
1334 '1' => array(1, 1, 1, 2, 1, 3, 1),
1335 '2' => array(1, 1, 1, 3, 1, 2, 2),
1336 '3' => array(1, 1, 1, 4, 1, 1, 3),
1337 '4' => array(1, 2, 1, 1, 1, 3, 4),
1338 '5' => array(1, 2, 1, 2, 1, 2, 5),
1339 '6' => array(1, 2, 1, 3, 1, 1, 6),
1340 '7' => array(1, 1, 1, 1, 1, 4, 7),
1341 '8' => array(1, 3, 1, 2, 1, 1, 8),
1342 '9' => array(1, 4, 1, 1, 1, 1, 9),
1343 'A' => array(2, 1, 1, 1, 1, 3, 10),
1344 'B' => array(2, 1, 1, 2, 1, 2, 11),
1345 'C' => array(2, 1, 1, 3, 1, 1, 12),
1346 'D' => array(2, 2, 1, 1, 1, 2, 13),
1347 'E' => array(2, 2, 1, 2, 1, 1, 14),
1348 'F' => array(2, 3, 1, 1, 1, 1, 15),
1349 'G' => array(1, 1, 2, 1, 1, 3, 16),
1350 'H' => array(1, 1, 2, 2, 1, 2, 17),
1351 'I' => array(1, 1, 2, 3, 1, 1, 18),
1352 'J' => array(1, 2, 2, 1, 1, 2, 19),
1353 'K' => array(1, 3, 2, 1, 1, 1, 20),
1354 'L' => array(1, 1, 1, 1, 2, 3, 21),
1355 'M' => array(1, 1, 1, 2, 2, 2, 22),
1356 'N' => array(1, 1, 1, 3, 2, 1, 23),
1357 'O' => array(1, 2, 1, 1, 2, 2, 24),
1358 'P' => array(1, 3, 1, 1, 2, 1, 25),
1359 'Q' => array(2, 1, 2, 1, 1, 2, 26),
1360 'R' => array(2, 1, 2, 2, 1, 1, 27),
1361 'S' => array(2, 1, 1, 1, 2, 2, 28),
1362 'T' => array(2, 1, 1, 2, 2, 1, 29),
1363 'U' => array(2, 2, 1, 1, 2, 1, 30),
1364 'V' => array(2, 2, 2, 1, 1, 1, 31),
1365 'W' => array(1, 1, 2, 1, 2, 2, 32),
1366 'X' => array(1, 1, 2, 2, 2, 1, 33),
1367 'Y' => array(1, 2, 2, 1, 2, 1, 34),
1368 'Z' => array(1, 2, 3, 1, 1, 1, 35),
1369 '-' => array(1, 2, 1, 1, 3, 1, 36),
1370 '.' => array(3, 1, 1, 1, 1, 2, 37),
1371 ' ' => array(3, 1, 1, 2, 1, 1, 38),
1372 '$' => array(3, 2, 1, 1, 1, 1, 39),
1373 '/' => array(1, 1, 2, 1, 3, 1, 40),
1374 '+' => array(1, 1, 3, 1, 2, 1, 41),
1375 '%' => array(2, 1, 1, 1, 3, 1, 42),
1376 '#' => array(1, 2, 1, 2, 2, 1, 43),
1377 '&' => array(3, 1, 2, 1, 1, 1, 44),
1378 '|' => array(3, 1, 1, 1, 2, 1, 45),
1379 '=' => array(1, 2, 2, 2, 1, 1, 46),
1380 '*' => array(1, 1, 1, 1, 4, 1, 0),
1383 private $code_93_asciibet = array(
1384 '&U',
'#A',
'#B',
'#C',
'#D',
'#E',
'#F',
'#G',
1385 '#H',
'#I',
'#J',
'#K',
'#L',
'#M',
'#N',
'#O',
1386 '#P',
'#Q',
'#R',
'#S',
'#T',
'#U',
'#V',
'#W',
1387 '#X',
'#Y',
'#Z',
'&A',
'&B',
'&C',
'&D',
'&E',
1388 ' ' ,
'|A',
'|B',
'|C',
'$' ,
'%' ,
'|F',
'|G',
1389 '|H',
'|I',
'|J',
'+' ,
'|L',
'-' ,
'.' ,
'/' ,
1390 '0' ,
'1' ,
'2' ,
'3' ,
'4' ,
'5' ,
'6' ,
'7' ,
1391 '8' ,
'9' ,
'|Z',
'&F',
'&G',
'&H',
'&I',
'&J',
1392 '&V',
'A' ,
'B' ,
'C' ,
'D' ,
'E' ,
'F' ,
'G' ,
1393 'H' ,
'I' ,
'J' ,
'K' ,
'L' ,
'M' ,
'N' ,
'O' ,
1394 'P' ,
'Q' ,
'R' ,
'S' ,
'T' ,
'U' ,
'V' ,
'W' ,
1395 'X' ,
'Y' ,
'Z' ,
'&K',
'&L',
'&M',
'&N',
'&O',
1396 '&W',
'=A',
'=B',
'=C',
'=D',
'=E',
'=F',
'=G',
1397 '=H',
'=I',
'=J',
'=K',
'=L',
'=M',
'=N',
'=O',
1398 '=P',
'=Q',
'=R',
'=S',
'=T',
'=U',
'=V',
'=W',
1399 '=X',
'=Y',
'=Z',
'&P',
'&Q',
'&R',
'&S',
'&T',
1404 private function code_128_encode($data, $dstate, $fnc1) {
1405 $data = preg_replace(
'/[\x80-\xFF]/',
'', $data);
1406 $label = preg_replace(
'/[\x00-\x1F\x7F]/',
' ', $data);
1407 $chars = $this->code_128_normalize($data, $dstate, $fnc1);
1408 $checksum = $chars[0] % 103;
1409 for ($i = 1, $n = count($chars); $i < $n; $i++) {
1410 $checksum += $i * $chars[$i];
1413 $chars[] = $checksum;
1416 $modules[] = array(0, 10, 0);
1417 foreach ($chars as $char) {
1418 $block = $this->code_128_alphabet[$char];
1419 foreach ($block as $i => $module) {
1420 $modules[] = array(($i & 1) ^ 1, $module, 1);
1423 $modules[] = array(0, 10, 0);
1424 $blocks = array(array(
'm' => $modules,
'l' => array($label)));
1425 return array(
'g' =>
'l',
'b' => $blocks);
1428 private function code_128_normalize($data, $dstate, $fnc1) {
1429 $detectcba =
'/(^[0-9]{4,}|^[0-9]{2}$)|([\x60-\x7F])|([\x00-\x1F])/';
1430 $detectc =
'/(^[0-9]{6,}|^[0-9]{4,}$)/';
1431 $detectba =
'/([\x60-\x7F])|([\x00-\x1F])/';
1432 $consumec =
'/(^[0-9]{2})/';
1433 $state = (($dstate > 0 && $dstate < 4) ? $dstate : 0);
1434 $abstate = ((abs($dstate) == 2) ? 2 : 1);
1435 $chars = array(102 + ($state ? $state : $abstate));
1436 if ($fnc1) $chars[] = 102;
1437 while (strlen($data)) {
1440 if (preg_match($detectcba, $data, $m)) {
1451 $chars = array(102 + $state);
1452 if ($fnc1) $chars[] = 102;
1455 if ($dstate <= 0 && preg_match($detectc, $data, $m)) {
1456 if (strlen($m[0]) % 2) {
1457 $data = substr($data, 1);
1458 $chars[] = 16 + substr($m[0], 0, 1);
1463 $ch = ord(substr($data, 0, 1));
1464 $data = substr($data, 1);
1466 $chars[] = $ch + 64;
1467 }
else if ($ch < 96) {
1468 $chars[] = $ch - 32;
1470 if (preg_match($detectba, $data, $m)) {
1480 $chars[] = $ch - 32;
1485 if ($dstate <= 0 && preg_match($detectc, $data, $m)) {
1486 if (strlen($m[0]) % 2) {
1487 $data = substr($data, 1);
1488 $chars[] = 16 + substr($m[0], 0, 1);
1493 $ch = ord(substr($data, 0, 1));
1494 $data = substr($data, 1);
1496 $chars[] = $ch - 32;
1498 if (preg_match($detectba, $data, $m)) {
1508 $chars[] = $ch + 64;
1513 if (preg_match($consumec, $data, $m)) {
1514 $data = substr($data, 2);
1515 $chars[] = (int)$m[0];
1517 if (preg_match($detectba, $data, $m)) {
1526 $chars[] = 102 - $state;
1534 private $code_128_alphabet = array(
1535 array(2, 1, 2, 2, 2, 2), array(2, 2, 2, 1, 2, 2),
1536 array(2, 2, 2, 2, 2, 1), array(1, 2, 1, 2, 2, 3),
1537 array(1, 2, 1, 3, 2, 2), array(1, 3, 1, 2, 2, 2),
1538 array(1, 2, 2, 2, 1, 3), array(1, 2, 2, 3, 1, 2),
1539 array(1, 3, 2, 2, 1, 2), array(2, 2, 1, 2, 1, 3),
1540 array(2, 2, 1, 3, 1, 2), array(2, 3, 1, 2, 1, 2),
1541 array(1, 1, 2, 2, 3, 2), array(1, 2, 2, 1, 3, 2),
1542 array(1, 2, 2, 2, 3, 1), array(1, 1, 3, 2, 2, 2),
1543 array(1, 2, 3, 1, 2, 2), array(1, 2, 3, 2, 2, 1),
1544 array(2, 2, 3, 2, 1, 1), array(2, 2, 1, 1, 3, 2),
1545 array(2, 2, 1, 2, 3, 1), array(2, 1, 3, 2, 1, 2),
1546 array(2, 2, 3, 1, 1, 2), array(3, 1, 2, 1, 3, 1),
1547 array(3, 1, 1, 2, 2, 2), array(3, 2, 1, 1, 2, 2),
1548 array(3, 2, 1, 2, 2, 1), array(3, 1, 2, 2, 1, 2),
1549 array(3, 2, 2, 1, 1, 2), array(3, 2, 2, 2, 1, 1),
1550 array(2, 1, 2, 1, 2, 3), array(2, 1, 2, 3, 2, 1),
1551 array(2, 3, 2, 1, 2, 1), array(1, 1, 1, 3, 2, 3),
1552 array(1, 3, 1, 1, 2, 3), array(1, 3, 1, 3, 2, 1),
1553 array(1, 1, 2, 3, 1, 3), array(1, 3, 2, 1, 1, 3),
1554 array(1, 3, 2, 3, 1, 1), array(2, 1, 1, 3, 1, 3),
1555 array(2, 3, 1, 1, 1, 3), array(2, 3, 1, 3, 1, 1),
1556 array(1, 1, 2, 1, 3, 3), array(1, 1, 2, 3, 3, 1),
1557 array(1, 3, 2, 1, 3, 1), array(1, 1, 3, 1, 2, 3),
1558 array(1, 1, 3, 3, 2, 1), array(1, 3, 3, 1, 2, 1),
1559 array(3, 1, 3, 1, 2, 1), array(2, 1, 1, 3, 3, 1),
1560 array(2, 3, 1, 1, 3, 1), array(2, 1, 3, 1, 1, 3),
1561 array(2, 1, 3, 3, 1, 1), array(2, 1, 3, 1, 3, 1),
1562 array(3, 1, 1, 1, 2, 3), array(3, 1, 1, 3, 2, 1),
1563 array(3, 3, 1, 1, 2, 1), array(3, 1, 2, 1, 1, 3),
1564 array(3, 1, 2, 3, 1, 1), array(3, 3, 2, 1, 1, 1),
1565 array(3, 1, 4, 1, 1, 1), array(2, 2, 1, 4, 1, 1),
1566 array(4, 3, 1, 1, 1, 1), array(1, 1, 1, 2, 2, 4),
1567 array(1, 1, 1, 4, 2, 2), array(1, 2, 1, 1, 2, 4),
1568 array(1, 2, 1, 4, 2, 1), array(1, 4, 1, 1, 2, 2),
1569 array(1, 4, 1, 2, 2, 1), array(1, 1, 2, 2, 1, 4),
1570 array(1, 1, 2, 4, 1, 2), array(1, 2, 2, 1, 1, 4),
1571 array(1, 2, 2, 4, 1, 1), array(1, 4, 2, 1, 1, 2),
1572 array(1, 4, 2, 2, 1, 1), array(2, 4, 1, 2, 1, 1),
1573 array(2, 2, 1, 1, 1, 4), array(4, 1, 3, 1, 1, 1),
1574 array(2, 4, 1, 1, 1, 2), array(1, 3, 4, 1, 1, 1),
1575 array(1, 1, 1, 2, 4, 2), array(1, 2, 1, 1, 4, 2),
1576 array(1, 2, 1, 2, 4, 1), array(1, 1, 4, 2, 1, 2),
1577 array(1, 2, 4, 1, 1, 2), array(1, 2, 4, 2, 1, 1),
1578 array(4, 1, 1, 2, 1, 2), array(4, 2, 1, 1, 1, 2),
1579 array(4, 2, 1, 2, 1, 1), array(2, 1, 2, 1, 4, 1),
1580 array(2, 1, 4, 1, 2, 1), array(4, 1, 2, 1, 2, 1),
1581 array(1, 1, 1, 1, 4, 3), array(1, 1, 1, 3, 4, 1),
1582 array(1, 3, 1, 1, 4, 1), array(1, 1, 4, 1, 1, 3),
1583 array(1, 1, 4, 3, 1, 1), array(4, 1, 1, 1, 1, 3),
1584 array(4, 1, 1, 3, 1, 1), array(1, 1, 3, 1, 4, 1),
1585 array(1, 1, 4, 1, 3, 1), array(3, 1, 1, 1, 4, 1),
1586 array(4, 1, 1, 1, 3, 1), array(2, 1, 1, 4, 1, 2),
1587 array(2, 1, 1, 2, 1, 4), array(2, 1, 1, 2, 3, 2),
1588 array(2, 3, 3, 1, 1, 1, 2)
1593 private function codabar_encode($data) {
1594 $data = strtoupper(preg_replace(
1595 '/[^0-9ABCDENTabcdent*.\/:+$-]/',
'', $data
1598 for ($i = 0, $n = strlen($data); $i < $n; $i++) {
1601 'm' => array(array(0, 1, 3))
1604 $char = substr($data, $i, 1);
1605 $block = $this->codabar_alphabet[$char];
1608 array(1, 1, $block[0]),
1609 array(0, 1, $block[1]),
1610 array(1, 1, $block[2]),
1611 array(0, 1, $block[3]),
1612 array(1, 1, $block[4]),
1613 array(0, 1, $block[5]),
1614 array(1, 1, $block[6]),
1619 return array(
'g' =>
'l',
'b' => $blocks);
1622 private $codabar_alphabet = array(
1623 '0' => array(1, 1, 1, 1, 1, 2, 2),
1624 '1' => array(1, 1, 1, 1, 2, 2, 1),
1625 '4' => array(1, 1, 2, 1, 1, 2, 1),
1626 '5' => array(2, 1, 1, 1, 1, 2, 1),
1627 '2' => array(1, 1, 1, 2, 1, 1, 2),
1628 '-' => array(1, 1, 1, 2, 2, 1, 1),
1629 '$' => array(1, 1, 2, 2, 1, 1, 1),
1630 '9' => array(2, 1, 1, 2, 1, 1, 1),
1631 '6' => array(1, 2, 1, 1, 1, 1, 2),
1632 '7' => array(1, 2, 1, 1, 2, 1, 1),
1633 '8' => array(1, 2, 2, 1, 1, 1, 1),
1634 '3' => array(2, 2, 1, 1, 1, 1, 1),
1635 'C' => array(1, 1, 1, 2, 1, 2, 2),
1636 'D' => array(1, 1, 1, 2, 2, 2, 1),
1637 'A' => array(1, 1, 2, 2, 1, 2, 1),
1638 'B' => array(1, 2, 1, 2, 1, 1, 2),
1639 '*' => array(1, 1, 1, 2, 1, 2, 2),
1640 'E' => array(1, 1, 1, 2, 2, 2, 1),
1641 'T' => array(1, 1, 2, 2, 1, 2, 1),
1642 'N' => array(1, 2, 1, 2, 1, 1, 2),
1643 '.' => array(2, 1, 2, 1, 2, 1, 1),
1644 '/' => array(2, 1, 2, 1, 1, 1, 2),
1645 ':' => array(2, 1, 1, 1, 2, 1, 2),
1646 '+' => array(1, 1, 2, 1, 2, 1, 2),
1651 private function itf_encode($data) {
1652 $data = preg_replace(
'/[^0-9]/',
'', $data);
1653 if (strlen($data) % 2) $data =
'0' . $data;
1657 'm' => array(array(0, 10, 0))
1668 for ($i = 0, $n = strlen($data); $i < $n; $i += 2) {
1669 $c1 = substr($data, $i, 1);
1670 $c2 = substr($data, $i+1, 1);
1671 $b1 = $this->itf_alphabet[$c1];
1672 $b2 = $this->itf_alphabet[$c2];
1675 array(1, 1, $b1[0]),
1676 array(0, 1, $b2[0]),
1677 array(1, 1, $b1[1]),
1678 array(0, 1, $b2[1]),
1679 array(1, 1, $b1[2]),
1680 array(0, 1, $b2[2]),
1681 array(1, 1, $b1[3]),
1682 array(0, 1, $b2[3]),
1683 array(1, 1, $b1[4]),
1684 array(0, 1, $b2[4]),
1686 'l' => array($c1 . $c2)
1698 'm' => array(array(0, 10, 0))
1701 return array(
'g' =>
'l',
'b' => $blocks);
1704 private $itf_alphabet = array(
1705 '0' => array(1, 1, 2, 2, 1),
1706 '1' => array(2, 1, 1, 1, 2),
1707 '2' => array(1, 2, 1, 1, 2),
1708 '3' => array(2, 2, 1, 1, 1),
1709 '4' => array(1, 1, 2, 1, 2),
1710 '5' => array(2, 1, 2, 1, 1),
1711 '6' => array(1, 2, 2, 1, 1),
1712 '7' => array(1, 1, 1, 2, 2),
1713 '8' => array(2, 1, 1, 2, 1),
1714 '9' => array(1, 2, 1, 2, 1),
1719 private function qr_encode($data, $ecl) {
1720 list($mode, $vers, $ec, $data) = $this->qr_encode_data($data, $ecl);
1721 $data = $this->qr_encode_ec($data, $ec, $vers);
1722 list($size, $mtx) = $this->qr_create_matrix($vers, $data);
1723 list($mask, $mtx) = $this->qr_apply_best_mask($mtx, $size);
1724 $mtx = $this->qr_finalize_matrix($mtx, $size, $ecl, $mask, $vers);
1727 'q' => array(4, 4, 4, 4),
1728 's' => array($size, $size),
1733 private function qr_encode_data($data, $ecl) {
1734 $mode = $this->qr_detect_mode($data);
1735 $version = $this->qr_detect_version($data, $mode, $ecl);
1736 $version_group = (($version < 10) ? 0 : (($version < 27) ? 1 : 2));
1737 $ec_params = $this->qr_ec_params[($version - 1) * 4 + $ecl];
1739 $max_chars = $this->qr_capacity[$version - 1][$ecl][$mode];
1740 if ($mode == 3) $max_chars <<= 1;
1741 $data = substr($data, 0, $max_chars);
1745 $code = $this->qr_encode_numeric($data, $version_group);
1748 $code = $this->qr_encode_alphanumeric($data, $version_group);
1751 $code = $this->qr_encode_binary($data, $version_group);
1754 $code = $this->qr_encode_kanji($data, $version_group);
1757 for ($i = 0; $i < 4; $i++) $code[] = 0;
1758 while (count($code) % 8) $code[] = 0;
1761 for ($i = 0, $n = count($code); $i < $n; $i += 8) {
1763 if ($code[$i + 0]) $byte |= 0x80;
1764 if ($code[$i + 1]) $byte |= 0x40;
1765 if ($code[$i + 2]) $byte |= 0x20;
1766 if ($code[$i + 3]) $byte |= 0x10;
1767 if ($code[$i + 4]) $byte |= 0x08;
1768 if ($code[$i + 5]) $byte |= 0x04;
1769 if ($code[$i + 6]) $byte |= 0x02;
1770 if ($code[$i + 7]) $byte |= 0x01;
1774 $i = count($data), $a = 1, $n = $ec_params[0];
1775 $i < $n; $i++, $a ^= 1
1777 $data[] = $a ? 236 : 17;
1780 return array($mode, $version, $ec_params, $data);
1783 private function qr_detect_mode($data) {
1784 $numeric =
'/^[0-9]*$/';
1785 $alphanumeric =
'/^[0-9A-Z .\/:$%*+-]*$/';
1786 $kanji =
'/^([\x81-\x9F\xE0-\xEA][\x40-\xFC]|[\xEB][\x40-\xBF])*$/';
1787 if (preg_match($numeric, $data))
return 0;
1788 if (preg_match($alphanumeric, $data))
return 1;
1789 if (preg_match($kanji, $data))
return 3;
1793 private function qr_detect_version($data, $mode, $ecl) {
1794 $length = strlen($data);
1795 if ($mode == 3) $length >>= 1;
1796 for ($v = 0; $v < 40; $v++) {
1797 if ($length <= $this->qr_capacity[$v][$ecl][$mode]) {
1804 private function qr_encode_numeric($data, $version_group) {
1805 $code = array(0, 0, 0, 1);
1806 $length = strlen($data);
1807 switch ($version_group) {
1809 $code[] = $length & 0x2000;
1810 $code[] = $length & 0x1000;
1812 $code[] = $length & 0x0800;
1813 $code[] = $length & 0x0400;
1815 $code[] = $length & 0x0200;
1816 $code[] = $length & 0x0100;
1817 $code[] = $length & 0x0080;
1818 $code[] = $length & 0x0040;
1819 $code[] = $length & 0x0020;
1820 $code[] = $length & 0x0010;
1821 $code[] = $length & 0x0008;
1822 $code[] = $length & 0x0004;
1823 $code[] = $length & 0x0002;
1824 $code[] = $length & 0x0001;
1826 for ($i = 0; $i < $length; $i += 3) {
1827 $group = substr($data, $i, 3);
1828 switch (strlen($group)) {
1830 $code[] = $group & 0x200;
1831 $code[] = $group & 0x100;
1832 $code[] = $group & 0x080;
1834 $code[] = $group & 0x040;
1835 $code[] = $group & 0x020;
1836 $code[] = $group & 0x010;
1838 $code[] = $group & 0x008;
1839 $code[] = $group & 0x004;
1840 $code[] = $group & 0x002;
1841 $code[] = $group & 0x001;
1847 private function qr_encode_alphanumeric($data, $version_group) {
1848 $alphabet =
'0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ $%*+-./:';
1849 $code = array(0, 0, 1, 0);
1850 $length = strlen($data);
1851 switch ($version_group) {
1853 $code[] = $length & 0x1000;
1854 $code[] = $length & 0x0800;
1856 $code[] = $length & 0x0400;
1857 $code[] = $length & 0x0200;
1859 $code[] = $length & 0x0100;
1860 $code[] = $length & 0x0080;
1861 $code[] = $length & 0x0040;
1862 $code[] = $length & 0x0020;
1863 $code[] = $length & 0x0010;
1864 $code[] = $length & 0x0008;
1865 $code[] = $length & 0x0004;
1866 $code[] = $length & 0x0002;
1867 $code[] = $length & 0x0001;
1869 for ($i = 0; $i < $length; $i += 2) {
1870 $group = substr($data, $i, 2);
1871 if (strlen($group) > 1) {
1872 $c1 = strpos($alphabet, substr($group, 0, 1));
1873 $c2 = strpos($alphabet, substr($group, 1, 1));
1874 $ch = $c1 * 45 + $c2;
1875 $code[] = $ch & 0x400;
1876 $code[] = $ch & 0x200;
1877 $code[] = $ch & 0x100;
1878 $code[] = $ch & 0x080;
1879 $code[] = $ch & 0x040;
1880 $code[] = $ch & 0x020;
1881 $code[] = $ch & 0x010;
1882 $code[] = $ch & 0x008;
1883 $code[] = $ch & 0x004;
1884 $code[] = $ch & 0x002;
1885 $code[] = $ch & 0x001;
1887 $ch = strpos($alphabet, $group);
1888 $code[] = $ch & 0x020;
1889 $code[] = $ch & 0x010;
1890 $code[] = $ch & 0x008;
1891 $code[] = $ch & 0x004;
1892 $code[] = $ch & 0x002;
1893 $code[] = $ch & 0x001;
1899 private function qr_encode_binary($data, $version_group) {
1900 $code = array(0, 1, 0, 0);
1901 $length = strlen($data);
1902 switch ($version_group) {
1905 $code[] = $length & 0x8000;
1906 $code[] = $length & 0x4000;
1907 $code[] = $length & 0x2000;
1908 $code[] = $length & 0x1000;
1909 $code[] = $length & 0x0800;
1910 $code[] = $length & 0x0400;
1911 $code[] = $length & 0x0200;
1912 $code[] = $length & 0x0100;
1914 $code[] = $length & 0x0080;
1915 $code[] = $length & 0x0040;
1916 $code[] = $length & 0x0020;
1917 $code[] = $length & 0x0010;
1918 $code[] = $length & 0x0008;
1919 $code[] = $length & 0x0004;
1920 $code[] = $length & 0x0002;
1921 $code[] = $length & 0x0001;
1923 for ($i = 0; $i < $length; $i++) {
1924 $ch = ord(substr($data, $i, 1));
1925 $code[] = $ch & 0x80;
1926 $code[] = $ch & 0x40;
1927 $code[] = $ch & 0x20;
1928 $code[] = $ch & 0x10;
1929 $code[] = $ch & 0x08;
1930 $code[] = $ch & 0x04;
1931 $code[] = $ch & 0x02;
1932 $code[] = $ch & 0x01;
1937 private function qr_encode_kanji($data, $version_group) {
1938 $code = array(1, 0, 0, 0);
1939 $length = strlen($data);
1940 switch ($version_group) {
1942 $code[] = $length & 0x1000;
1943 $code[] = $length & 0x0800;
1945 $code[] = $length & 0x0400;
1946 $code[] = $length & 0x0200;
1948 $code[] = $length & 0x0100;
1949 $code[] = $length & 0x0080;
1950 $code[] = $length & 0x0040;
1951 $code[] = $length & 0x0020;
1952 $code[] = $length & 0x0010;
1953 $code[] = $length & 0x0008;
1954 $code[] = $length & 0x0004;
1955 $code[] = $length & 0x0002;
1957 for ($i = 0; $i < $length; $i += 2) {
1958 $group = substr($data, $i, 2);
1959 $c1 = ord(substr($group, 0, 1));
1960 $c2 = ord(substr($group, 1, 1));
1961 if ($c1 >= 0x81 && $c1 <= 0x9F && $c2 >= 0x40 && $c2 <= 0xFC) {
1962 $ch = ($c1 - 0x81) * 0xC0 + ($c2 - 0x40);
1964 ($c1 >= 0xE0 && $c1 <= 0xEA && $c2 >= 0x40 && $c2 <= 0xFC) ||
1965 ($c1 == 0xEB && $c2 >= 0x40 && $c2 <= 0xBF)
1967 $ch = ($c1 - 0xC1) * 0xC0 + ($c2 - 0x40);
1971 $code[] = $ch & 0x1000;
1972 $code[] = $ch & 0x0800;
1973 $code[] = $ch & 0x0400;
1974 $code[] = $ch & 0x0200;
1975 $code[] = $ch & 0x0100;
1976 $code[] = $ch & 0x0080;
1977 $code[] = $ch & 0x0040;
1978 $code[] = $ch & 0x0020;
1979 $code[] = $ch & 0x0010;
1980 $code[] = $ch & 0x0008;
1981 $code[] = $ch & 0x0004;
1982 $code[] = $ch & 0x0002;
1983 $code[] = $ch & 0x0001;
1988 private function qr_encode_ec($data, $ec_params, $version) {
1989 $blocks = $this->qr_ec_split($data, $ec_params);
1990 $ec_blocks = array();
1991 for ($i = 0, $n = count($blocks); $i < $n; $i++) {
1992 $ec_blocks[] = $this->qr_ec_divide($blocks[$i], $ec_params);
1994 $data = $this->qr_ec_interleave($blocks);
1995 $ec_data = $this->qr_ec_interleave($ec_blocks);
1997 foreach ($data as $ch) {
1998 $code[] = $ch & 0x80;
1999 $code[] = $ch & 0x40;
2000 $code[] = $ch & 0x20;
2001 $code[] = $ch & 0x10;
2002 $code[] = $ch & 0x08;
2003 $code[] = $ch & 0x04;
2004 $code[] = $ch & 0x02;
2005 $code[] = $ch & 0x01;
2007 foreach ($ec_data as $ch) {
2008 $code[] = $ch & 0x80;
2009 $code[] = $ch & 0x40;
2010 $code[] = $ch & 0x20;
2011 $code[] = $ch & 0x10;
2012 $code[] = $ch & 0x08;
2013 $code[] = $ch & 0x04;
2014 $code[] = $ch & 0x02;
2015 $code[] = $ch & 0x01;
2017 for ($n = $this->qr_remainder_bits[$version - 1]; $n > 0; $n--) {
2023 private function qr_ec_split($data, $ec_params) {
2026 for ($i = $ec_params[2], $length = $ec_params[3]; $i > 0; $i--) {
2027 $blocks[] = array_slice($data, $offset, $length);
2030 for ($i = $ec_params[4], $length = $ec_params[5]; $i > 0; $i--) {
2031 $blocks[] = array_slice($data, $offset, $length);
2037 private function qr_ec_divide($data, $ec_params) {
2038 $num_data = count($data);
2039 $num_error = $ec_params[1];
2040 $generator = $this->qr_ec_polynomials[$num_error];
2042 for ($i = 0; $i < $num_error; $i++) {
2045 for ($i = 0; $i < $num_data; $i++) {
2047 $leadterm = $this->qr_log[$message[$i]];
2048 for ($j = 0; $j <= $num_error; $j++) {
2049 $term = ($generator[$j] + $leadterm) % 255;
2050 $message[$i + $j] ^= $this->qr_exp[$term];
2054 return array_slice($message, $num_data, $num_error);
2057 private function qr_ec_interleave($blocks) {
2059 $num_blocks = count($blocks);
2060 for ($offset = 0;
true; $offset++) {
2062 for ($i = 0; $i < $num_blocks; $i++) {
2063 if (isset($blocks[$i][$offset])) {
2064 $data[] = $blocks[$i][$offset];
2073 private function qr_create_matrix($version, $data) {
2074 $size = $version * 4 + 17;
2076 for ($i = 0; $i < $size; $i++) {
2078 for ($j = 0; $j < $size; $j++) {
2084 for ($i = 0; $i < 8; $i++) {
2085 for ($j = 0; $j < 8; $j++) {
2086 $m = (($i == 7 || $j == 7) ? 2 :
2087 (($i == 0 || $j == 0 || $i == 6 || $j == 6) ? 3 :
2088 (($i == 1 || $j == 1 || $i == 5 || $j == 5) ? 2 : 3)));
2089 $matrix[$i][$j] = $m;
2090 $matrix[$size - $i - 1][$j] = $m;
2091 $matrix[$i][$size - $j - 1] = $m;
2095 if ($version >= 2) {
2096 $alignment = $this->qr_alignment_patterns[$version - 2];
2097 foreach ($alignment as $i) {
2098 foreach ($alignment as $j) {
2099 if (!$matrix[$i][$j]) {
2100 for ($ii = -2; $ii <= 2; $ii++) {
2101 for ($jj = -2; $jj <= 2; $jj++) {
2102 $m = (max(abs($ii), abs($jj)) & 1) ^ 3;
2103 $matrix[$i + $ii][$j + $jj] = $m;
2111 for ($i = $size - 9; $i >= 8; $i--) {
2112 $matrix[$i][6] = ($i & 1) ^ 3;
2113 $matrix[6][$i] = ($i & 1) ^ 3;
2116 $matrix[$size - 8][8] = 3;
2118 for ($i = 0; $i <= 8; $i++) {
2119 if (!$matrix[$i][8]) $matrix[$i][8] = 1;
2120 if (!$matrix[8][$i]) $matrix[8][$i] = 1;
2121 if ($i && !$matrix[$size - $i][8]) $matrix[$size - $i][8] = 1;
2122 if ($i && !$matrix[8][$size - $i]) $matrix[8][$size - $i] = 1;
2125 if ($version >= 7) {
2126 for ($i = 9; $i < 12; $i++) {
2127 for ($j = 0; $j < 6; $j++) {
2128 $matrix[$size - $i][$j] = 1;
2129 $matrix[$j][$size - $i] = 1;
2138 $length = count($data);
2139 while ($col > 0 && $offset < $length) {
2140 if (!$matrix[$row][$col]) {
2141 $matrix[$row][$col] = $data[$offset] ? 5 : 4;
2144 if (!$matrix[$row][$col - 1]) {
2145 $matrix[$row][$col - 1] = $data[$offset] ? 5 : 4;
2149 if ($row < 0 || $row >= $size) {
2153 if ($col == 6) $col--;
2156 return array($size, $matrix);
2159 private function qr_apply_best_mask($matrix, $size) {
2161 $best_matrix = $this->qr_apply_mask($matrix, $size, $best_mask);
2162 $best_penalty = $this->qr_penalty($best_matrix, $size);
2163 for ($test_mask = 1; $test_mask < 8; $test_mask++) {
2164 $test_matrix = $this->qr_apply_mask($matrix, $size, $test_mask);
2165 $test_penalty = $this->qr_penalty($test_matrix, $size);
2166 if ($test_penalty < $best_penalty) {
2167 $best_mask = $test_mask;
2168 $best_matrix = $test_matrix;
2169 $best_penalty = $test_penalty;
2172 return array($best_mask, $best_matrix);
2175 private function qr_apply_mask($matrix, $size, $mask) {
2176 for ($i = 0; $i < $size; $i++) {
2177 for ($j = 0; $j < $size; $j++) {
2178 if ($matrix[$i][$j] >= 4) {
2179 if ($this->qr_mask($mask, $i, $j)) {
2180 $matrix[$i][$j] ^= 1;
2188 private function qr_mask($mask, $r, $c) {
2190 case 0:
return !( ($r + $c) % 2 );
2191 case 1:
return !( ($r ) % 2 );
2192 case 2:
return !( ( $c) % 3 );
2193 case 3:
return !( ($r + $c) % 3 );
2194 case 4:
return !( (floor(($r) / 2) + floor(($c) / 3)) % 2 );
2195 case 5:
return !( ((($r * $c) % 2) + (($r * $c) % 3)) );
2196 case 6:
return !( ((($r * $c) % 2) + (($r * $c) % 3)) % 2 );
2197 case 7:
return !( ((($r + $c) % 2) + (($r * $c) % 3)) % 2 );
2201 private function qr_penalty(&$matrix, $size) {
2202 $score = $this->qr_penalty_1($matrix, $size);
2203 $score += $this->qr_penalty_2($matrix, $size);
2204 $score += $this->qr_penalty_3($matrix, $size);
2205 $score += $this->qr_penalty_4($matrix, $size);
2209 private function qr_penalty_1(&$matrix, $size) {
2211 for ($i = 0; $i < $size; $i++) {
2216 for ($j = 0; $j < $size; $j++) {
2217 $rv = ($matrix[$i][$j] == 5 || $matrix[$i][$j] == 3) ? 1 : 0;
2218 $cv = ($matrix[$j][$i] == 5 || $matrix[$j][$i] == 3) ? 1 : 0;
2219 if ($rv == $rowvalue) {
2222 if ($rowcount >= 5) $score += $rowcount - 2;
2226 if ($cv == $colvalue) {
2229 if ($colcount >= 5) $score += $colcount - 2;
2234 if ($rowcount >= 5) $score += $rowcount - 2;
2235 if ($colcount >= 5) $score += $colcount - 2;
2240 private function qr_penalty_2(&$matrix, $size) {
2242 for ($i = 1; $i < $size; $i++) {
2243 for ($j = 1; $j < $size; $j++) {
2244 $v1 = $matrix[$i - 1][$j - 1];
2245 $v2 = $matrix[$i - 1][$j ];
2246 $v3 = $matrix[$i ][$j - 1];
2247 $v4 = $matrix[$i ][$j ];
2248 $v1 = ($v1 == 5 || $v1 == 3) ? 1 : 0;
2249 $v2 = ($v2 == 5 || $v2 == 3) ? 1 : 0;
2250 $v3 = ($v3 == 5 || $v3 == 3) ? 1 : 0;
2251 $v4 = ($v4 == 5 || $v4 == 3) ? 1 : 0;
2252 if ($v1 == $v2 && $v2 == $v3 && $v3 == $v4) $score += 3;
2258 private function qr_penalty_3(&$matrix, $size) {
2260 for ($i = 0; $i < $size; $i++) {
2263 for ($j = 0; $j < 11; $j++) {
2264 $rv = ($matrix[$i][$j] == 5 || $matrix[$i][$j] == 3) ? 1 : 0;
2265 $cv = ($matrix[$j][$i] == 5 || $matrix[$j][$i] == 3) ? 1 : 0;
2266 $rowvalue = (($rowvalue << 1) & 0x7FF) | $rv;
2267 $colvalue = (($colvalue << 1) & 0x7FF) | $cv;
2269 if ($rowvalue == 0x5D0 || $rowvalue == 0x5D) $score += 40;
2270 if ($colvalue == 0x5D0 || $colvalue == 0x5D) $score += 40;
2271 for ($j = 11; $j < $size; $j++) {
2272 $rv = ($matrix[$i][$j] == 5 || $matrix[$i][$j] == 3) ? 1 : 0;
2273 $cv = ($matrix[$j][$i] == 5 || $matrix[$j][$i] == 3) ? 1 : 0;
2274 $rowvalue = (($rowvalue << 1) & 0x7FF) | $rv;
2275 $colvalue = (($colvalue << 1) & 0x7FF) | $cv;
2276 if ($rowvalue == 0x5D0 || $rowvalue == 0x5D) $score += 40;
2277 if ($colvalue == 0x5D0 || $colvalue == 0x5D) $score += 40;
2283 private function qr_penalty_4(&$matrix, $size) {
2285 for ($i = 0; $i < $size; $i++) {
2286 for ($j = 0; $j < $size; $j++) {
2287 if ($matrix[$i][$j] == 5 || $matrix[$i][$j] == 3) {
2293 $dark /= $size * $size;
2294 $a = abs(floor($dark) - 10);
2295 $b = abs(ceil($dark) - 10);
2296 return min($a, $b) * 10;
2299 private function qr_finalize_matrix(
2300 $matrix, $size, $ecl, $mask, $version
2303 $format = $this->qr_format_info[$ecl * 8 + $mask];
2304 $matrix[8][0] = $format[0];
2305 $matrix[8][1] = $format[1];
2306 $matrix[8][2] = $format[2];
2307 $matrix[8][3] = $format[3];
2308 $matrix[8][4] = $format[4];
2309 $matrix[8][5] = $format[5];
2310 $matrix[8][7] = $format[6];
2311 $matrix[8][8] = $format[7];
2312 $matrix[7][8] = $format[8];
2313 $matrix[5][8] = $format[9];
2314 $matrix[4][8] = $format[10];
2315 $matrix[3][8] = $format[11];
2316 $matrix[2][8] = $format[12];
2317 $matrix[1][8] = $format[13];
2318 $matrix[0][8] = $format[14];
2319 $matrix[$size - 1][8] = $format[0];
2320 $matrix[$size - 2][8] = $format[1];
2321 $matrix[$size - 3][8] = $format[2];
2322 $matrix[$size - 4][8] = $format[3];
2323 $matrix[$size - 5][8] = $format[4];
2324 $matrix[$size - 6][8] = $format[5];
2325 $matrix[$size - 7][8] = $format[6];
2326 $matrix[8][$size - 8] = $format[7];
2327 $matrix[8][$size - 7] = $format[8];
2328 $matrix[8][$size - 6] = $format[9];
2329 $matrix[8][$size - 5] = $format[10];
2330 $matrix[8][$size - 4] = $format[11];
2331 $matrix[8][$size - 3] = $format[12];
2332 $matrix[8][$size - 2] = $format[13];
2333 $matrix[8][$size - 1] = $format[14];
2335 if ($version >= 7) {
2336 $version = $this->qr_version_info[$version - 7];
2337 for ($i = 0; $i < 18; $i++) {
2338 $r = $size - 9 - ($i % 3);
2339 $c = 5 - floor($i / 3);
2340 $matrix[$r][$c] = $version[$i];
2341 $matrix[$c][$r] = $version[$i];
2345 for ($i = 0; $i < $size; $i++) {
2346 for ($j = 0; $j < $size; $j++) {
2347 $matrix[$i][$j] &= 1;
2356 private $qr_capacity = array(
2357 array(array( 41, 25, 17, 10), array( 34, 20, 14, 8),
2358 array( 27, 16, 11, 7), array( 17, 10, 7, 4)),
2359 array(array( 77, 47, 32, 20), array( 63, 38, 26, 16),
2360 array( 48, 29, 20, 12), array( 34, 20, 14, 8)),
2361 array(array( 127, 77, 53, 32), array( 101, 61, 42, 26),
2362 array( 77, 47, 32, 20), array( 58, 35, 24, 15)),
2363 array(array( 187, 114, 78, 48), array( 149, 90, 62, 38),
2364 array( 111, 67, 46, 28), array( 82, 50, 34, 21)),
2365 array(array( 255, 154, 106, 65), array( 202, 122, 84, 52),
2366 array( 144, 87, 60, 37), array( 106, 64, 44, 27)),
2367 array(array( 322, 195, 134, 82), array( 255, 154, 106, 65),
2368 array( 178, 108, 74, 45), array( 139, 84, 58, 36)),
2369 array(array( 370, 224, 154, 95), array( 293, 178, 122, 75),
2370 array( 207, 125, 86, 53), array( 154, 93, 64, 39)),
2371 array(array( 461, 279, 192, 118), array( 365, 221, 152, 93),
2372 array( 259, 157, 108, 66), array( 202, 122, 84, 52)),
2373 array(array( 552, 335, 230, 141), array( 432, 262, 180, 111),
2374 array( 312, 189, 130, 80), array( 235, 143, 98, 60)),
2375 array(array( 652, 395, 271, 167), array( 513, 311, 213, 131),
2376 array( 364, 221, 151, 93), array( 288, 174, 119, 74)),
2377 array(array( 772, 468, 321, 198), array( 604, 366, 251, 155),
2378 array( 427, 259, 177, 109), array( 331, 200, 137, 85)),
2379 array(array( 883, 535, 367, 226), array( 691, 419, 287, 177),
2380 array( 489, 296, 203, 125), array( 374, 227, 155, 96)),
2381 array(array(1022, 619, 425, 262), array( 796, 483, 331, 204),
2382 array( 580, 352, 241, 149), array( 427, 259, 177, 109)),
2383 array(array(1101, 667, 458, 282), array( 871, 528, 362, 223),
2384 array( 621, 376, 258, 159), array( 468, 283, 194, 120)),
2385 array(array(1250, 758, 520, 320), array( 991, 600, 412, 254),
2386 array( 703, 426, 292, 180), array( 530, 321, 220, 136)),
2387 array(array(1408, 854, 586, 361), array(1082, 656, 450, 277),
2388 array( 775, 470, 322, 198), array( 602, 365, 250, 154)),
2389 array(array(1548, 938, 644, 397), array(1212, 734, 504, 310),
2390 array( 876, 531, 364, 224), array( 674, 408, 280, 173)),
2391 array(array(1725, 1046, 718, 442), array(1346, 816, 560, 345),
2392 array( 948, 574, 394, 243), array( 746, 452, 310, 191)),
2393 array(array(1903, 1153, 792, 488), array(1500, 909, 624, 384),
2394 array(1063, 644, 442, 272), array( 813, 493, 338, 208)),
2395 array(array(2061, 1249, 858, 528), array(1600, 970, 666, 410),
2396 array(1159, 702, 482, 297), array( 919, 557, 382, 235)),
2397 array(array(2232, 1352, 929, 572), array(1708, 1035, 711, 438),
2398 array(1224, 742, 509, 314), array( 969, 587, 403, 248)),
2399 array(array(2409, 1460, 1003, 618), array(1872, 1134, 779, 480),
2400 array(1358, 823, 565, 348), array(1056, 640, 439, 270)),
2401 array(array(2620, 1588, 1091, 672), array(2059, 1248, 857, 528),
2402 array(1468, 890, 611, 376), array(1108, 672, 461, 284)),
2403 array(array(2812, 1704, 1171, 721), array(2188, 1326, 911, 561),
2404 array(1588, 963, 661, 407), array(1228, 744, 511, 315)),
2405 array(array(3057, 1853, 1273, 784), array(2395, 1451, 997, 614),
2406 array(1718, 1041, 715, 440), array(1286, 779, 535, 330)),
2407 array(array(3283, 1990, 1367, 842), array(2544, 1542, 1059, 652),
2408 array(1804, 1094, 751, 462), array(1425, 864, 593, 365)),
2409 array(array(3517, 2132, 1465, 902), array(2701, 1637, 1125, 692),
2410 array(1933, 1172, 805, 496), array(1501, 910, 625, 385)),
2411 array(array(3669, 2223, 1528, 940), array(2857, 1732, 1190, 732),
2412 array(2085, 1263, 868, 534), array(1581, 958, 658, 405)),
2413 array(array(3909, 2369, 1628, 1002), array(3035, 1839, 1264, 778),
2414 array(2181, 1322, 908, 559), array(1677, 1016, 698, 430)),
2415 array(array(4158, 2520, 1732, 1066), array(3289, 1994, 1370, 843),
2416 array(2358, 1429, 982, 604), array(1782, 1080, 742, 457)),
2417 array(array(4417, 2677, 1840, 1132), array(3486, 2113, 1452, 894),
2418 array(2473, 1499, 1030, 634), array(1897, 1150, 790, 486)),
2419 array(array(4686, 2840, 1952, 1201), array(3693, 2238, 1538, 947),
2420 array(2670, 1618, 1112, 684), array(2022, 1226, 842, 518)),
2421 array(array(4965, 3009, 2068, 1273), array(3909, 2369, 1628, 1002),
2422 array(2805, 1700, 1168, 719), array(2157, 1307, 898, 553)),
2423 array(array(5253, 3183, 2188, 1347), array(4134, 2506, 1722, 1060),
2424 array(2949, 1787, 1228, 756), array(2301, 1394, 958, 590)),
2425 array(array(5529, 3351, 2303, 1417), array(4343, 2632, 1809, 1113),
2426 array(3081, 1867, 1283, 790), array(2361, 1431, 983, 605)),
2427 array(array(5836, 3537, 2431, 1496), array(4588, 2780, 1911, 1176),
2428 array(3244, 1966, 1351, 832), array(2524, 1530, 1051, 647)),
2429 array(array(6153, 3729, 2563, 1577), array(4775, 2894, 1989, 1224),
2430 array(3417, 2071, 1423, 876), array(2625, 1591, 1093, 673)),
2431 array(array(6479, 3927, 2699, 1661), array(5039, 3054, 2099, 1292),
2432 array(3599, 2181, 1499, 923), array(2735, 1658, 1139, 701)),
2433 array(array(6743, 4087, 2809, 1729), array(5313, 3220, 2213, 1362),
2434 array(3791, 2298, 1579, 972), array(2927, 1774, 1219, 750)),
2435 array(array(7089, 4296, 2953, 1817), array(5596, 3391, 2331, 1435),
2436 array(3993, 2420, 1663, 1024), array(3057, 1852, 1273, 784)),
2449 private $qr_ec_params = array(
2450 array( 19, 7, 1, 19, 0, 0 ),
2451 array( 16, 10, 1, 16, 0, 0 ),
2452 array( 13, 13, 1, 13, 0, 0 ),
2453 array( 9, 17, 1, 9, 0, 0 ),
2454 array( 34, 10, 1, 34, 0, 0 ),
2455 array( 28, 16, 1, 28, 0, 0 ),
2456 array( 22, 22, 1, 22, 0, 0 ),
2457 array( 16, 28, 1, 16, 0, 0 ),
2458 array( 55, 15, 1, 55, 0, 0 ),
2459 array( 44, 26, 1, 44, 0, 0 ),
2460 array( 34, 18, 2, 17, 0, 0 ),
2461 array( 26, 22, 2, 13, 0, 0 ),
2462 array( 80, 20, 1, 80, 0, 0 ),
2463 array( 64, 18, 2, 32, 0, 0 ),
2464 array( 48, 26, 2, 24, 0, 0 ),
2465 array( 36, 16, 4, 9, 0, 0 ),
2466 array( 108, 26, 1, 108, 0, 0 ),
2467 array( 86, 24, 2, 43, 0, 0 ),
2468 array( 62, 18, 2, 15, 2, 16 ),
2469 array( 46, 22, 2, 11, 2, 12 ),
2470 array( 136, 18, 2, 68, 0, 0 ),
2471 array( 108, 16, 4, 27, 0, 0 ),
2472 array( 76, 24, 4, 19, 0, 0 ),
2473 array( 60, 28, 4, 15, 0, 0 ),
2474 array( 156, 20, 2, 78, 0, 0 ),
2475 array( 124, 18, 4, 31, 0, 0 ),
2476 array( 88, 18, 2, 14, 4, 15 ),
2477 array( 66, 26, 4, 13, 1, 14 ),
2478 array( 194, 24, 2, 97, 0, 0 ),
2479 array( 154, 22, 2, 38, 2, 39 ),
2480 array( 110, 22, 4, 18, 2, 19 ),
2481 array( 86, 26, 4, 14, 2, 15 ),
2482 array( 232, 30, 2, 116, 0, 0 ),
2483 array( 182, 22, 3, 36, 2, 37 ),
2484 array( 132, 20, 4, 16, 4, 17 ),
2485 array( 100, 24, 4, 12, 4, 13 ),
2486 array( 274, 18, 2, 68, 2, 69 ),
2487 array( 216, 26, 4, 43, 1, 44 ),
2488 array( 154, 24, 6, 19, 2, 20 ),
2489 array( 122, 28, 6, 15, 2, 16 ),
2490 array( 324, 20, 4, 81, 0, 0 ),
2491 array( 254, 30, 1, 50, 4, 51 ),
2492 array( 180, 28, 4, 22, 4, 23 ),
2493 array( 140, 24, 3, 12, 8, 13 ),
2494 array( 370, 24, 2, 92, 2, 93 ),
2495 array( 290, 22, 6, 36, 2, 37 ),
2496 array( 206, 26, 4, 20, 6, 21 ),
2497 array( 158, 28, 7, 14, 4, 15 ),
2498 array( 428, 26, 4, 107, 0, 0 ),
2499 array( 334, 22, 8, 37, 1, 38 ),
2500 array( 244, 24, 8, 20, 4, 21 ),
2501 array( 180, 22, 12, 11, 4, 12 ),
2502 array( 461, 30, 3, 115, 1, 116 ),
2503 array( 365, 24, 4, 40, 5, 41 ),
2504 array( 261, 20, 11, 16, 5, 17 ),
2505 array( 197, 24, 11, 12, 5, 13 ),
2506 array( 523, 22, 5, 87, 1, 88 ),
2507 array( 415, 24, 5, 41, 5, 42 ),
2508 array( 295, 30, 5, 24, 7, 25 ),
2509 array( 223, 24, 11, 12, 7, 13 ),
2510 array( 589, 24, 5, 98, 1, 99 ),
2511 array( 453, 28, 7, 45, 3, 46 ),
2512 array( 325, 24, 15, 19, 2, 20 ),
2513 array( 253, 30, 3, 15, 13, 16 ),
2514 array( 647, 28, 1, 107, 5, 108 ),
2515 array( 507, 28, 10, 46, 1, 47 ),
2516 array( 367, 28, 1, 22, 15, 23 ),
2517 array( 283, 28, 2, 14, 17, 15 ),
2518 array( 721, 30, 5, 120, 1, 121 ),
2519 array( 563, 26, 9, 43, 4, 44 ),
2520 array( 397, 28, 17, 22, 1, 23 ),
2521 array( 313, 28, 2, 14, 19, 15 ),
2522 array( 795, 28, 3, 113, 4, 114 ),
2523 array( 627, 26, 3, 44, 11, 45 ),
2524 array( 445, 26, 17, 21, 4, 22 ),
2525 array( 341, 26, 9, 13, 16, 14 ),
2526 array( 861, 28, 3, 107, 5, 108 ),
2527 array( 669, 26, 3, 41, 13, 42 ),
2528 array( 485, 30, 15, 24, 5, 25 ),
2529 array( 385, 28, 15, 15, 10, 16 ),
2530 array( 932, 28, 4, 116, 4, 117 ),
2531 array( 714, 26, 17, 42, 0, 0 ),
2532 array( 512, 28, 17, 22, 6, 23 ),
2533 array( 406, 30, 19, 16, 6, 17 ),
2534 array( 1006, 28, 2, 111, 7, 112 ),
2535 array( 782, 28, 17, 46, 0, 0 ),
2536 array( 568, 30, 7, 24, 16, 25 ),
2537 array( 442, 24, 34, 13, 0, 0 ),
2538 array( 1094, 30, 4, 121, 5, 122 ),
2539 array( 860, 28, 4, 47, 14, 48 ),
2540 array( 614, 30, 11, 24, 14, 25 ),
2541 array( 464, 30, 16, 15, 14, 16 ),
2542 array( 1174, 30, 6, 117, 4, 118 ),
2543 array( 914, 28, 6, 45, 14, 46 ),
2544 array( 664, 30, 11, 24, 16, 25 ),
2545 array( 514, 30, 30, 16, 2, 17 ),
2546 array( 1276, 26, 8, 106, 4, 107 ),
2547 array( 1000, 28, 8, 47, 13, 48 ),
2548 array( 718, 30, 7, 24, 22, 25 ),
2549 array( 538, 30, 22, 15, 13, 16 ),
2550 array( 1370, 28, 10, 114, 2, 115 ),
2551 array( 1062, 28, 19, 46, 4, 47 ),
2552 array( 754, 28, 28, 22, 6, 23 ),
2553 array( 596, 30, 33, 16, 4, 17 ),
2554 array( 1468, 30, 8, 122, 4, 123 ),
2555 array( 1128, 28, 22, 45, 3, 46 ),
2556 array( 808, 30, 8, 23, 26, 24 ),
2557 array( 628, 30, 12, 15, 28, 16 ),
2558 array( 1531, 30, 3, 117, 10, 118 ),
2559 array( 1193, 28, 3, 45, 23, 46 ),
2560 array( 871, 30, 4, 24, 31, 25 ),
2561 array( 661, 30, 11, 15, 31, 16 ),
2562 array( 1631, 30, 7, 116, 7, 117 ),
2563 array( 1267, 28, 21, 45, 7, 46 ),
2564 array( 911, 30, 1, 23, 37, 24 ),
2565 array( 701, 30, 19, 15, 26, 16 ),
2566 array( 1735, 30, 5, 115, 10, 116 ),
2567 array( 1373, 28, 19, 47, 10, 48 ),
2568 array( 985, 30, 15, 24, 25, 25 ),
2569 array( 745, 30, 23, 15, 25, 16 ),
2570 array( 1843, 30, 13, 115, 3, 116 ),
2571 array( 1455, 28, 2, 46, 29, 47 ),
2572 array( 1033, 30, 42, 24, 1, 25 ),
2573 array( 793, 30, 23, 15, 28, 16 ),
2574 array( 1955, 30, 17, 115, 0, 0 ),
2575 array( 1541, 28, 10, 46, 23, 47 ),
2576 array( 1115, 30, 10, 24, 35, 25 ),
2577 array( 845, 30, 19, 15, 35, 16 ),
2578 array( 2071, 30, 17, 115, 1, 116 ),
2579 array( 1631, 28, 14, 46, 21, 47 ),
2580 array( 1171, 30, 29, 24, 19, 25 ),
2581 array( 901, 30, 11, 15, 46, 16 ),
2582 array( 2191, 30, 13, 115, 6, 116 ),
2583 array( 1725, 28, 14, 46, 23, 47 ),
2584 array( 1231, 30, 44, 24, 7, 25 ),
2585 array( 961, 30, 59, 16, 1, 17 ),
2586 array( 2306, 30, 12, 121, 7, 122 ),
2587 array( 1812, 28, 12, 47, 26, 48 ),
2588 array( 1286, 30, 39, 24, 14, 25 ),
2589 array( 986, 30, 22, 15, 41, 16 ),
2590 array( 2434, 30, 6, 121, 14, 122 ),
2591 array( 1914, 28, 6, 47, 34, 48 ),
2592 array( 1354, 30, 46, 24, 10, 25 ),
2593 array( 1054, 30, 2, 15, 64, 16 ),
2594 array( 2566, 30, 17, 122, 4, 123 ),
2595 array( 1992, 28, 29, 46, 14, 47 ),
2596 array( 1426, 30, 49, 24, 10, 25 ),
2597 array( 1096, 30, 24, 15, 46, 16 ),
2598 array( 2702, 30, 4, 122, 18, 123 ),
2599 array( 2102, 28, 13, 46, 32, 47 ),
2600 array( 1502, 30, 48, 24, 14, 25 ),
2601 array( 1142, 30, 42, 15, 32, 16 ),
2602 array( 2812, 30, 20, 117, 4, 118 ),
2603 array( 2216, 28, 40, 47, 7, 48 ),
2604 array( 1582, 30, 43, 24, 22, 25 ),
2605 array( 1222, 30, 10, 15, 67, 16 ),
2606 array( 2956, 30, 19, 118, 6, 119 ),
2607 array( 2334, 28, 18, 47, 31, 48 ),
2608 array( 1666, 30, 34, 24, 34, 25 ),
2609 array( 1276, 30, 20, 15, 61, 16 ),
2612 private $qr_ec_polynomials = array(
2614 0, 87, 229, 146, 149, 238, 102, 21
2617 0, 251, 67, 46, 61, 118, 70, 64, 94, 32, 45
2620 0, 74, 152, 176, 100, 86, 100,
2621 106, 104, 130, 218, 206, 140, 78
2624 0, 8, 183, 61, 91, 202, 37, 51,
2625 58, 58, 237, 140, 124, 5, 99, 105
2628 0, 120, 104, 107, 109, 102, 161, 76, 3,
2629 91, 191, 147, 169, 182, 194, 225, 120
2632 0, 43, 139, 206, 78, 43, 239, 123, 206,
2633 214, 147, 24, 99, 150, 39, 243, 163, 136
2636 0, 215, 234, 158, 94, 184, 97, 118, 170, 79,
2637 187, 152, 148, 252, 179, 5, 98, 96, 153
2640 0, 17, 60, 79, 50, 61, 163, 26, 187, 202, 180,
2641 221, 225, 83, 239, 156, 164, 212, 212, 188, 190
2644 0, 210, 171, 247, 242, 93, 230, 14, 109, 221, 53, 200,
2645 74, 8, 172, 98, 80, 219, 134, 160, 105, 165, 231
2648 0, 229, 121, 135, 48, 211, 117, 251, 126, 159, 180, 169,
2649 152, 192, 226, 228, 218, 111, 0, 117, 232, 87, 96, 227, 21
2652 0, 173, 125, 158, 2, 103, 182, 118, 17,
2653 145, 201, 111, 28, 165, 53, 161, 21, 245,
2654 142, 13, 102, 48, 227, 153, 145, 218, 70
2657 0, 168, 223, 200, 104, 224, 234, 108, 180,
2658 110, 190, 195, 147, 205, 27, 232, 201, 21, 43,
2659 245, 87, 42, 195, 212, 119, 242, 37, 9, 123
2662 0, 41, 173, 145, 152, 216, 31, 179, 182, 50, 48,
2663 110, 86, 239, 96, 222, 125, 42, 173, 226, 193,
2664 224, 130, 156, 37, 251, 216, 238, 40, 192, 180
2668 private $qr_log = array(
2669 0, 0, 1, 25, 2, 50, 26, 198,
2670 3, 223, 51, 238, 27, 104, 199, 75,
2671 4, 100, 224, 14, 52, 141, 239, 129,
2672 28, 193, 105, 248, 200, 8, 76, 113,
2673 5, 138, 101, 47, 225, 36, 15, 33,
2674 53, 147, 142, 218, 240, 18, 130, 69,
2675 29, 181, 194, 125, 106, 39, 249, 185,
2676 201, 154, 9, 120, 77, 228, 114, 166,
2677 6, 191, 139, 98, 102, 221, 48, 253,
2678 226, 152, 37, 179, 16, 145, 34, 136,
2679 54, 208, 148, 206, 143, 150, 219, 189,
2680 241, 210, 19, 92, 131, 56, 70, 64,
2681 30, 66, 182, 163, 195, 72, 126, 110,
2682 107, 58, 40, 84, 250, 133, 186, 61,
2683 202, 94, 155, 159, 10, 21, 121, 43,
2684 78, 212, 229, 172, 115, 243, 167, 87,
2685 7, 112, 192, 247, 140, 128, 99, 13,
2686 103, 74, 222, 237, 49, 197, 254, 24,
2687 227, 165, 153, 119, 38, 184, 180, 124,
2688 17, 68, 146, 217, 35, 32, 137, 46,
2689 55, 63, 209, 91, 149, 188, 207, 205,
2690 144, 135, 151, 178, 220, 252, 190, 97,
2691 242, 86, 211, 171, 20, 42, 93, 158,
2692 132, 60, 57, 83, 71, 109, 65, 162,
2693 31, 45, 67, 216, 183, 123, 164, 118,
2694 196, 23, 73, 236, 127, 12, 111, 246,
2695 108, 161, 59, 82, 41, 157, 85, 170,
2696 251, 96, 134, 177, 187, 204, 62, 90,
2697 203, 89, 95, 176, 156, 169, 160, 81,
2698 11, 245, 22, 235, 122, 117, 44, 215,
2699 79, 174, 213, 233, 230, 231, 173, 232,
2700 116, 214, 244, 234, 168, 80, 88, 175,
2703 private $qr_exp = array(
2704 1, 2, 4, 8, 16, 32, 64, 128,
2705 29, 58, 116, 232, 205, 135, 19, 38,
2706 76, 152, 45, 90, 180, 117, 234, 201,
2707 143, 3, 6, 12, 24, 48, 96, 192,
2708 157, 39, 78, 156, 37, 74, 148, 53,
2709 106, 212, 181, 119, 238, 193, 159, 35,
2710 70, 140, 5, 10, 20, 40, 80, 160,
2711 93, 186, 105, 210, 185, 111, 222, 161,
2712 95, 190, 97, 194, 153, 47, 94, 188,
2713 101, 202, 137, 15, 30, 60, 120, 240,
2714 253, 231, 211, 187, 107, 214, 177, 127,
2715 254, 225, 223, 163, 91, 182, 113, 226,
2716 217, 175, 67, 134, 17, 34, 68, 136,
2717 13, 26, 52, 104, 208, 189, 103, 206,
2718 129, 31, 62, 124, 248, 237, 199, 147,
2719 59, 118, 236, 197, 151, 51, 102, 204,
2720 133, 23, 46, 92, 184, 109, 218, 169,
2721 79, 158, 33, 66, 132, 21, 42, 84,
2722 168, 77, 154, 41, 82, 164, 85, 170,
2723 73, 146, 57, 114, 228, 213, 183, 115,
2724 230, 209, 191, 99, 198, 145, 63, 126,
2725 252, 229, 215, 179, 123, 246, 241, 255,
2726 227, 219, 171, 75, 150, 49, 98, 196,
2727 149, 55, 110, 220, 165, 87, 174, 65,
2728 130, 25, 50, 100, 200, 141, 7, 14,
2729 28, 56, 112, 224, 221, 167, 83, 166,
2730 81, 162, 89, 178, 121, 242, 249, 239,
2731 195, 155, 43, 86, 172, 69, 138, 9,
2732 18, 36, 72, 144, 61, 122, 244, 245,
2733 247, 243, 251, 235, 203, 139, 11, 22,
2734 44, 88, 176, 125, 250, 233, 207, 131,
2735 27, 54, 108, 216, 173, 71, 142, 1,
2738 private $qr_remainder_bits = array(
2739 0, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 3,
2740 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0,
2743 private $qr_alignment_patterns = array(
2756 array(6, 26, 46, 66),
2757 array(6, 26, 48, 70),
2758 array(6, 26, 50, 74),
2759 array(6, 30, 54, 78),
2760 array(6, 30, 56, 82),
2761 array(6, 30, 58, 86),
2762 array(6, 34, 62, 90),
2763 array(6, 28, 50, 72, 94),
2764 array(6, 26, 50, 74, 98),
2765 array(6, 30, 54, 78, 102),
2766 array(6, 28, 54, 80, 106),
2767 array(6, 32, 58, 84, 110),
2768 array(6, 30, 58, 86, 114),
2769 array(6, 34, 62, 90, 118),
2770 array(6, 26, 50, 74, 98, 122),
2771 array(6, 30, 54, 78, 102, 126),
2772 array(6, 26, 52, 78, 104, 130),
2773 array(6, 30, 56, 82, 108, 134),
2774 array(6, 34, 60, 86, 112, 138),
2775 array(6, 30, 58, 86, 114, 142),
2776 array(6, 34, 62, 90, 118, 146),
2777 array(6, 30, 54, 78, 102, 126, 150),
2778 array(6, 24, 50, 76, 102, 128, 154),
2779 array(6, 28, 54, 80, 106, 132, 158),
2780 array(6, 32, 58, 84, 110, 136, 162),
2781 array(6, 26, 54, 82, 110, 138, 166),
2782 array(6, 30, 58, 86, 114, 142, 170),
2788 private $qr_format_info = array(
2789 array( 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0 ),
2790 array( 1, 1, 1, 0, 0, 1, 0, 1, 1, 1, 1, 0, 0, 1, 1 ),
2791 array( 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0 ),
2792 array( 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 1 ),
2793 array( 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 1 ),
2794 array( 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0 ),
2795 array( 1, 1, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1 ),
2796 array( 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 0 ),
2797 array( 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0 ),
2798 array( 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1 ),
2799 array( 1, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0 ),
2800 array( 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1 ),
2801 array( 1, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1 ),
2802 array( 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0 ),
2803 array( 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 0, 1, 1, 1 ),
2804 array( 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0 ),
2805 array( 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1 ),
2806 array( 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0 ),
2807 array( 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1 ),
2808 array( 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0 ),
2809 array( 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0 ),
2810 array( 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1 ),
2811 array( 0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0 ),
2812 array( 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1 ),
2813 array( 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1 ),
2814 array( 0, 0, 1, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0 ),
2815 array( 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1 ),
2816 array( 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0 ),
2817 array( 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 1, 0 ),
2818 array( 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1 ),
2819 array( 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0 ),
2820 array( 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1 ),
2824 private $qr_version_info = array(
2825 array( 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0 ),
2826 array( 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0 ),
2827 array( 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1 ),
2828 array( 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1 ),
2829 array( 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0 ),
2830 array( 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 1, 0 ),
2831 array( 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1 ),
2832 array( 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 1 ),
2833 array( 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0 ),
2834 array( 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0 ),
2835 array( 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 1 ),
2836 array( 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 1 ),
2837 array( 0, 1, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0 ),
2838 array( 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0 ),
2839 array( 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 1, 1 ),
2840 array( 0, 1, 0, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1 ),
2841 array( 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0 ),
2842 array( 0, 1, 1, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 1, 0, 0 ),
2843 array( 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1 ),
2844 array( 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1 ),
2845 array( 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0 ),
2846 array( 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0 ),
2847 array( 0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1 ),
2848 array( 0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1 ),
2849 array( 0, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0 ),
2850 array( 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1 ),
2851 array( 1, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0 ),
2852 array( 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 1, 0 ),
2853 array( 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1 ),
2854 array( 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0, 1, 1 ),
2855 array( 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 1, 0 ),
2856 array( 1, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0 ),
2857 array( 1, 0, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1 ),
2858 array( 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1 ),
2863 private function dmtx_encode($data, $rect, $fnc1) {
2864 list($data, $ec) = $this->dmtx_encode_data($data, $rect, $fnc1);
2865 $data = $this->dmtx_encode_ec($data, $ec);
2866 list($h, $w, $mtx) = $this->dmtx_create_matrix($ec, $data);
2869 'q' => array(1, 1, 1, 1),
2870 's' => array($w, $h),
2875 private function dmtx_encode_data($data, $rect, $fnc1) {
2877 $edata = ($fnc1 ? array(232) : array());
2878 $length = strlen($data);
2880 while ($offset < $length) {
2881 $ch1 = ord(substr($data, $offset, 1));
2883 if ($ch1 >= 0x30 && $ch1 <= 0x39) {
2884 $ch2 = ord(substr($data, $offset, 1));
2885 if ($ch2 >= 0x30 && $ch2 <= 0x39) {
2887 $edata[] = (($ch1 - 0x30) * 10) + ($ch2 - 0x30) + 130;
2889 $edata[] = $ch1 + 1;
2891 }
else if ($ch1 < 0x80) {
2892 $edata[] = $ch1 + 1;
2895 $edata[] = ($ch1 - 0x80) + 1;
2899 $length = count($edata);
2900 $ec_params = $this->dmtx_detect_version($length, $rect);
2901 if ($length > $ec_params[0]) {
2902 $length = $ec_params[0];
2903 $edata = array_slice($edata, 0, $length);
2904 if ($edata[$length - 1] == 235) {
2905 $edata[$length - 1] = 129;
2907 }
else if ($length < $ec_params[0]) {
2910 while ($length < $ec_params[0]) {
2912 $r = (($length * 149) % 253) + 1;
2913 $edata[] = ($r + 129) % 254;
2917 return array($edata, $ec_params);
2920 private function dmtx_detect_version($length, $rect) {
2921 for ($i = ($rect ? 24 : 0), $j = ($rect ? 30 : 24); $i < $j; $i++) {
2922 if ($length <= $this->dmtx_ec_params[$i][0]) {
2923 return $this->dmtx_ec_params[$i];
2926 return $this->dmtx_ec_params[$j - 1];
2929 private function dmtx_encode_ec($data, $ec_params) {
2930 $blocks = $this->dmtx_ec_split($data, $ec_params);
2931 for ($i = 0, $n = count($blocks); $i < $n; $i++) {
2932 $ec_block = $this->dmtx_ec_divide($blocks[$i], $ec_params);
2933 $blocks[$i] = array_merge($blocks[$i], $ec_block);
2935 return $this->dmtx_ec_interleave($blocks);
2938 private function dmtx_ec_split($data, $ec_params) {
2940 $num_blocks = $ec_params[2] + $ec_params[4];
2941 for ($i = 0; $i < $num_blocks; $i++) {
2942 $blocks[$i] = array();
2944 for ($i = 0, $length = count($data); $i < $length; $i++) {
2945 $blocks[$i % $num_blocks][] = $data[$i];
2950 private function dmtx_ec_divide($data, $ec_params) {
2951 $num_data = count($data);
2952 $num_error = $ec_params[1];
2953 $generator = $this->dmtx_ec_polynomials[$num_error];
2955 for ($i = 0; $i < $num_error; $i++) {
2958 for ($i = 0; $i < $num_data; $i++) {
2960 $leadterm = $this->dmtx_log[$message[$i]];
2961 for ($j = 0; $j <= $num_error; $j++) {
2962 $term = ($generator[$j] + $leadterm) % 255;
2963 $message[$i + $j] ^= $this->dmtx_exp[$term];
2967 return array_slice($message, $num_data, $num_error);
2970 private function dmtx_ec_interleave($blocks) {
2972 $num_blocks = count($blocks);
2973 for ($offset = 0;
true; $offset++) {
2975 for ($i = 0; $i < $num_blocks; $i++) {
2976 if (isset($blocks[$i][$offset])) {
2977 $data[] = $blocks[$i][$offset];
2986 private function dmtx_create_matrix($ec_params, $data) {
2988 $rheight = $ec_params[8] + 2;
2989 $rwidth = $ec_params[9] + 2;
2990 $height = $ec_params[6] * $rheight;
2991 $width = $ec_params[7] * $rwidth;
2993 for ($y = 0; $y < $height; $y++) {
2995 for ($x = 0; $x <
$width; $x++) {
2997 ((($x + $y) % 2) == 0) ||
2998 (($x % $rwidth) == 0) ||
2999 (($y % $rheight) == ($rheight - 1))
3005 $rows = $ec_params[6] * $ec_params[8];
3006 $cols = $ec_params[7] * $ec_params[9];
3008 for ($y = 0; $y < $rows; $y++) {
3010 for ($x = 0; $x <
$width; $x++) {
3015 $this->dmtx_place_data($matrix, $rows, $cols, $data);
3017 for ($yy = 0; $yy < $ec_params[6]; $yy++) {
3018 for ($xx = 0; $xx < $ec_params[7]; $xx++) {
3019 for ($y = 0; $y < $ec_params[8]; $y++) {
3020 for ($x = 0; $x < $ec_params[9]; $x++) {
3021 $row = $yy * $ec_params[8] + $y;
3022 $col = $xx * $ec_params[9] + $x;
3023 $b = $matrix[$row][$col];
3024 if (is_null($b))
continue;
3025 $row = $yy * $rheight + $y + 1;
3026 $col = $xx * $rwidth + $x + 1;
3027 $bitmap[$row][$col] = $b;
3033 return array($height, $width, $bitmap);
3036 private function dmtx_place_data(&$mtx, $rows, $cols, $data) {
3040 $length = count($data);
3041 while (($row < $rows || $col < $cols) && $offset < $length) {
3043 if ($row == $rows && $col == 0) {
3044 $this->dmtx_place_1($mtx, $rows, $cols, $data[$offset++]);
3045 }
else if ($row == $rows - 2 && $col == 0 && $cols % 4 != 0) {
3046 $this->dmtx_place_2($mtx, $rows, $cols, $data[$offset++]);
3047 }
else if ($row == $rows - 2 && $col == 0 && $cols % 8 == 4) {
3048 $this->dmtx_place_3($mtx, $rows, $cols, $data[$offset++]);
3049 }
else if ($row == $rows + 4 && $col == 2 && $cols % 8 == 0) {
3050 $this->dmtx_place_4($mtx, $rows, $cols, $data[$offset++]);
3053 while ($row >= 0 && $col < $cols && $offset < $length) {
3054 if ($row < $rows && $col >= 0 && is_null($mtx[$row][$col])) {
3055 $b = $data[$offset++];
3056 $this->dmtx_place_0($mtx, $rows, $cols, $row, $col, $b);
3064 while ($row < $rows && $col >= 0 && $offset < $length) {
3065 if ($row >= 0 && $col < $cols && is_null($mtx[$row][$col])) {
3066 $b = $data[$offset++];
3067 $this->dmtx_place_0($mtx, $rows, $cols, $row, $col, $b);
3077 private function dmtx_place_1(&$matrix, $rows, $cols, $b) {
3078 $matrix[$rows - 1][0] = (($b & 0x80) ? 1 : 0);
3079 $matrix[$rows - 1][1] = (($b & 0x40) ? 1 : 0);
3080 $matrix[$rows - 1][2] = (($b & 0x20) ? 1 : 0);
3081 $matrix[0][$cols - 2] = (($b & 0x10) ? 1 : 0);
3082 $matrix[0][$cols - 1] = (($b & 0x08) ? 1 : 0);
3083 $matrix[1][$cols - 1] = (($b & 0x04) ? 1 : 0);
3084 $matrix[2][$cols - 1] = (($b & 0x02) ? 1 : 0);
3085 $matrix[3][$cols - 1] = (($b & 0x01) ? 1 : 0);
3088 private function dmtx_place_2(&$matrix, $rows, $cols, $b) {
3089 $matrix[$rows - 3][0] = (($b & 0x80) ? 1 : 0);
3090 $matrix[$rows - 2][0] = (($b & 0x40) ? 1 : 0);
3091 $matrix[$rows - 1][0] = (($b & 0x20) ? 1 : 0);
3092 $matrix[0][$cols - 4] = (($b & 0x10) ? 1 : 0);
3093 $matrix[0][$cols - 3] = (($b & 0x08) ? 1 : 0);
3094 $matrix[0][$cols - 2] = (($b & 0x04) ? 1 : 0);
3095 $matrix[0][$cols - 1] = (($b & 0x02) ? 1 : 0);
3096 $matrix[1][$cols - 1] = (($b & 0x01) ? 1 : 0);
3099 private function dmtx_place_3(&$matrix, $rows, $cols, $b) {
3100 $matrix[$rows - 3][0] = (($b & 0x80) ? 1 : 0);
3101 $matrix[$rows - 2][0] = (($b & 0x40) ? 1 : 0);
3102 $matrix[$rows - 1][0] = (($b & 0x20) ? 1 : 0);
3103 $matrix[0][$cols - 2] = (($b & 0x10) ? 1 : 0);
3104 $matrix[0][$cols - 1] = (($b & 0x08) ? 1 : 0);
3105 $matrix[1][$cols - 1] = (($b & 0x04) ? 1 : 0);
3106 $matrix[2][$cols - 1] = (($b & 0x02) ? 1 : 0);
3107 $matrix[3][$cols - 1] = (($b & 0x01) ? 1 : 0);
3110 private function dmtx_place_4(&$matrix, $rows, $cols, $b) {
3111 $matrix[$rows - 1][ 0] = (($b & 0x80) ? 1 : 0);
3112 $matrix[$rows - 1][$cols - 1] = (($b & 0x40) ? 1 : 0);
3113 $matrix[ 0][$cols - 3] = (($b & 0x20) ? 1 : 0);
3114 $matrix[ 0][$cols - 2] = (($b & 0x10) ? 1 : 0);
3115 $matrix[ 0][$cols - 1] = (($b & 0x08) ? 1 : 0);
3116 $matrix[ 1][$cols - 3] = (($b & 0x04) ? 1 : 0);
3117 $matrix[ 1][$cols - 2] = (($b & 0x02) ? 1 : 0);
3118 $matrix[ 1][$cols - 1] = (($b & 0x01) ? 1 : 0);
3121 private function dmtx_place_0(&$matrix, $rows, $cols, $row, $col, $b) {
3122 $this->dmtx_place_b($matrix, $rows, $cols, $row-2, $col-2, $b & 0x80);
3123 $this->dmtx_place_b($matrix, $rows, $cols, $row-2, $col-1, $b & 0x40);
3124 $this->dmtx_place_b($matrix, $rows, $cols, $row-1, $col-2, $b & 0x20);
3125 $this->dmtx_place_b($matrix, $rows, $cols, $row-1, $col-1, $b & 0x10);
3126 $this->dmtx_place_b($matrix, $rows, $cols, $row-1, $col-0, $b & 0x08);
3127 $this->dmtx_place_b($matrix, $rows, $cols, $row-0, $col-2, $b & 0x04);
3128 $this->dmtx_place_b($matrix, $rows, $cols, $row-0, $col-1, $b & 0x02);
3129 $this->dmtx_place_b($matrix, $rows, $cols, $row-0, $col-0, $b & 0x01);
3132 private function dmtx_place_b(&$matrix, $rows, $cols, $row, $col, $b) {
3135 $col += (4 - (($rows + 4) % 8));
3139 $row += (4 - (($cols + 4) % 8));
3141 $matrix[$row][$col] = ($b ? 1 : 0);
3156 private $dmtx_ec_params = array(
3157 array( 3, 5, 1, 3, 0, 0, 1, 1, 8, 8 ),
3158 array( 5, 7, 1, 5, 0, 0, 1, 1, 10, 10 ),
3159 array( 8, 10, 1, 8, 0, 0, 1, 1, 12, 12 ),
3160 array( 12, 12, 1, 12, 0, 0, 1, 1, 14, 14 ),
3161 array( 18, 14, 1, 18, 0, 0, 1, 1, 16, 16 ),
3162 array( 22, 18, 1, 22, 0, 0, 1, 1, 18, 18 ),
3163 array( 30, 20, 1, 30, 0, 0, 1, 1, 20, 20 ),
3164 array( 36, 24, 1, 36, 0, 0, 1, 1, 22, 22 ),
3165 array( 44, 28, 1, 44, 0, 0, 1, 1, 24, 24 ),
3166 array( 62, 36, 1, 62, 0, 0, 2, 2, 14, 14 ),
3167 array( 86, 42, 1, 86, 0, 0, 2, 2, 16, 16 ),
3168 array( 114, 48, 1, 114, 0, 0, 2, 2, 18, 18 ),
3169 array( 144, 56, 1, 144, 0, 0, 2, 2, 20, 20 ),
3170 array( 174, 68, 1, 174, 0, 0, 2, 2, 22, 22 ),
3171 array( 204, 42, 2, 102, 0, 0, 2, 2, 24, 24 ),
3172 array( 280, 56, 2, 140, 0, 0, 4, 4, 14, 14 ),
3173 array( 368, 36, 4, 92, 0, 0, 4, 4, 16, 16 ),
3174 array( 456, 48, 4, 114, 0, 0, 4, 4, 18, 18 ),
3175 array( 576, 56, 4, 144, 0, 0, 4, 4, 20, 20 ),
3176 array( 696, 68, 4, 174, 0, 0, 4, 4, 22, 22 ),
3177 array( 816, 56, 6, 136, 0, 0, 4, 4, 24, 24 ),
3178 array( 1050, 68, 6, 175, 0, 0, 6, 6, 18, 18 ),
3179 array( 1304, 62, 8, 163, 0, 0, 6, 6, 20, 20 ),
3180 array( 1558, 62, 8, 156, 2, 155, 6, 6, 22, 22 ),
3181 array( 5, 7, 1, 5, 0, 0, 1, 1, 6, 16 ),
3182 array( 10, 11, 1, 10, 0, 0, 1, 2, 6, 14 ),
3183 array( 16, 14, 1, 16, 0, 0, 1, 1, 10, 24 ),
3184 array( 22, 18, 1, 22, 0, 0, 1, 2, 10, 16 ),
3185 array( 32, 24, 1, 32, 0, 0, 1, 2, 14, 16 ),
3186 array( 49, 28, 1, 49, 0, 0, 1, 2, 14, 22 ),
3189 private $dmtx_ec_polynomials = array(
3191 0, 235, 207, 210, 244, 15
3194 0, 177, 30, 214, 218, 42, 197, 28
3197 0, 199, 50, 150, 120, 237, 131, 172, 83, 243, 55
3200 0, 213, 173, 212, 156, 103, 109, 174, 242, 215, 12, 66
3203 0, 168, 142, 35, 173, 94, 185, 107, 199, 74, 194, 233, 78
3206 0, 83, 171, 33, 39, 8, 12, 248,
3207 27, 38, 84, 93, 246, 173, 105
3210 0, 164, 9, 244, 69, 177, 163, 161, 231, 94,
3211 250, 199, 220, 253, 164, 103, 142, 61, 171
3214 0, 127, 33, 146, 23, 79, 25, 193, 122, 209, 233,
3215 230, 164, 1, 109, 184, 149, 38, 201, 61, 210
3218 0, 65, 141, 245, 31, 183, 242, 236, 177, 127, 225, 106,
3219 22, 131, 20, 202, 22, 106, 137, 103, 231, 215, 136, 85, 45
3222 0, 150, 32, 109, 149, 239, 213, 198, 48, 94,
3223 50, 12, 195, 167, 130, 196, 253, 99, 166, 239,
3224 222, 146, 190, 245, 184, 173, 125, 17, 151
3227 0, 57, 86, 187, 69, 140, 153, 31, 66, 135, 67, 248, 84,
3228 90, 81, 219, 197, 2, 1, 39, 16, 75, 229, 20, 51, 252,
3229 108, 213, 181, 183, 87, 111, 77, 232, 168, 176, 156
3232 0, 225, 38, 225, 148, 192, 254, 141, 11, 82, 237,
3233 81, 24, 13, 122, 0, 106, 167, 13, 207, 160, 88,
3234 203, 38, 142, 84, 66, 3, 168, 102, 156, 1, 200,
3235 88, 60, 233, 134, 115, 114, 234, 90, 65, 138
3238 0, 114, 69, 122, 30, 94, 11, 66, 230, 132, 73, 145, 137,
3239 135, 79, 214, 33, 12, 220, 142, 213, 136, 124, 215, 166,
3240 9, 222, 28, 154, 132, 4, 100, 170, 145, 59, 164, 215, 17,
3241 249, 102, 249, 134, 128, 5, 245, 131, 127, 221, 156
3244 0, 29, 179, 99, 149, 159, 72, 125, 22, 55, 60, 217,
3245 176, 156, 90, 43, 80, 251, 235, 128, 169, 254, 134,
3246 249, 42, 121, 118, 72, 128, 129, 232, 37, 15, 24, 221,
3247 143, 115, 131, 40, 113, 254, 19, 123, 246, 68, 166,
3248 66, 118, 142, 47, 51, 195, 242, 249, 131, 38, 66
3251 0, 182, 133, 162, 126, 236, 58, 172, 163, 53, 121, 159, 2,
3252 166, 137, 234, 158, 195, 164, 77, 228, 226, 145, 91, 180,
3253 232, 23, 241, 132, 135, 206, 184, 14, 6, 66, 238, 83, 100,
3254 111, 85, 202, 91, 156, 68, 218, 57, 83, 222, 188, 25, 179,
3255 144, 169, 164, 82, 154, 103, 89, 42, 141, 175, 32, 168
3258 0, 33, 79, 190, 245, 91, 221, 233, 25, 24, 6, 144,
3259 151, 121, 186, 140, 127, 45, 153, 250, 183, 70, 131,
3260 198, 17, 89, 245, 121, 51, 140, 252, 203, 82, 83, 233,
3261 152, 220, 155, 18, 230, 210, 94, 32, 200, 197, 192,
3262 194, 202, 129, 10, 237, 198, 94, 176, 36, 40, 139,
3263 201, 132, 219, 34, 56, 113, 52, 20, 34, 247, 15, 51
3267 private $dmtx_log = array(
3268 0, 0, 1, 240, 2, 225, 241, 53,
3269 3, 38, 226, 133, 242, 43, 54, 210,
3270 4, 195, 39, 114, 227, 106, 134, 28,
3271 243, 140, 44, 23, 55, 118, 211, 234,
3272 5, 219, 196, 96, 40, 222, 115, 103,
3273 228, 78, 107, 125, 135, 8, 29, 162,
3274 244, 186, 141, 180, 45, 99, 24, 49,
3275 56, 13, 119, 153, 212, 199, 235, 91,
3276 6, 76, 220, 217, 197, 11, 97, 184,
3277 41, 36, 223, 253, 116, 138, 104, 193,
3278 229, 86, 79, 171, 108, 165, 126, 145,
3279 136, 34, 9, 74, 30, 32, 163, 84,
3280 245, 173, 187, 204, 142, 81, 181, 190,
3281 46, 88, 100, 159, 25, 231, 50, 207,
3282 57, 147, 14, 67, 120, 128, 154, 248,
3283 213, 167, 200, 63, 236, 110, 92, 176,
3284 7, 161, 77, 124, 221, 102, 218, 95,
3285 198, 90, 12, 152, 98, 48, 185, 179,
3286 42, 209, 37, 132, 224, 52, 254, 239,
3287 117, 233, 139, 22, 105, 27, 194, 113,
3288 230, 206, 87, 158, 80, 189, 172, 203,
3289 109, 175, 166, 62, 127, 247, 146, 66,
3290 137, 192, 35, 252, 10, 183, 75, 216,
3291 31, 83, 33, 73, 164, 144, 85, 170,
3292 246, 65, 174, 61, 188, 202, 205, 157,
3293 143, 169, 82, 72, 182, 215, 191, 251,
3294 47, 178, 89, 151, 101, 94, 160, 123,
3295 26, 112, 232, 21, 51, 238, 208, 131,
3296 58, 69, 148, 18, 15, 16, 68, 17,
3297 121, 149, 129, 19, 155, 59, 249, 70,
3298 214, 250, 168, 71, 201, 156, 64, 60,
3299 237, 130, 111, 20, 93, 122, 177, 150,
3302 private $dmtx_exp = array(
3303 1, 2, 4, 8, 16, 32, 64, 128,
3304 45, 90, 180, 69, 138, 57, 114, 228,
3305 229, 231, 227, 235, 251, 219, 155, 27,
3306 54, 108, 216, 157, 23, 46, 92, 184,
3307 93, 186, 89, 178, 73, 146, 9, 18,
3308 36, 72, 144, 13, 26, 52, 104, 208,
3309 141, 55, 110, 220, 149, 7, 14, 28,
3310 56, 112, 224, 237, 247, 195, 171, 123,
3311 246, 193, 175, 115, 230, 225, 239, 243,
3312 203, 187, 91, 182, 65, 130, 41, 82,
3313 164, 101, 202, 185, 95, 190, 81, 162,
3314 105, 210, 137, 63, 126, 252, 213, 135,
3315 35, 70, 140, 53, 106, 212, 133, 39,
3316 78, 156, 21, 42, 84, 168, 125, 250,
3317 217, 159, 19, 38, 76, 152, 29, 58,
3318 116, 232, 253, 215, 131, 43, 86, 172,
3319 117, 234, 249, 223, 147, 11, 22, 44,
3320 88, 176, 77, 154, 25, 50, 100, 200,
3321 189, 87, 174, 113, 226, 233, 255, 211,
3322 139, 59, 118, 236, 245, 199, 163, 107,
3323 214, 129, 47, 94, 188, 85, 170, 121,
3324 242, 201, 191, 83, 166, 97, 194, 169,
3325 127, 254, 209, 143, 51, 102, 204, 181,
3326 71, 142, 49, 98, 196, 165, 103, 206,
3327 177, 79, 158, 17, 34, 68, 136, 61,
3328 122, 244, 197, 167, 99, 198, 161, 111,
3329 222, 145, 15, 30, 60, 120, 240, 205,
3330 183, 67, 134, 33, 66, 132, 37, 74,
3331 148, 5, 10, 20, 40, 80, 160, 109,
3332 218, 153, 31, 62, 124, 248, 221, 151,
3333 3, 6, 12, 24, 48, 96, 192, 173,
3334 119, 238, 241, 207, 179, 75, 150, 1,