46 public function get_image_html($format, $symbology, $data, $options): string {
49 switch (strtolower(preg_replace(
'/[^A-Za-z0-9]/',
'', $format))) {
51 $image = $this->
render_image($symbology, $data, $options);
57 $image = $this->
render_image($symbology, $data, $options);
62 case 'jpg':
case 'jpe':
case 'jpeg':
63 $image = $this->
render_image($symbology, $data, $options);
69 $svg = $this->
render_svg($symbology, $data, $options);
70 return '<img src="data:image/svg+xml;base64,' . base64_encode($svg) .
'" />';
75 $data = ob_get_clean();
76 return '<img src="data:' . $mime .
';base64,' . base64_encode($data) .
'" />';
80 public function output_image($format, $symbology, $data, $options) {
81 switch (strtolower(preg_replace(
'/[^A-Za-z0-9]/',
'', $format))) {
83 header(
'Content-Type: image/png');
84 $image = $this->
render_image($symbology, $data, $options);
89 header(
'Content-Type: image/gif');
90 $image = $this->
render_image($symbology, $data, $options);
94 case 'jpg':
case 'jpe':
case 'jpeg':
95 header(
'Content-Type: image/jpeg');
96 $image = $this->
render_image($symbology, $data, $options);
101 header(
'Content-Type: image/svg+xml');
102 echo $this->
render_svg($symbology, $data, $options);
108 list($code, $widths, $width, $height, $x, $y, $w, $h) =
109 $this->encode_and_calculate_size($symbology, $data, $options);
110 $image = imagecreatetruecolor($width, $height);
111 imagesavealpha($image,
true);
112 $bgcolor = (isset($options[
'bc']) ? $options[
'bc'] :
'FFF');
114 $bgcolor = $this->allocate_color($image, $bgcolor);
115 imagefill($image, 0, 0, $bgcolor);
117 (isset($options[
'cs']) ? $options[
'cs'] :
''),
118 (isset($options[
'cm']) ? $options[
'cm'] :
'000'),
119 (isset($options[
'c2']) ? $options[
'c2'] :
'F00'),
120 (isset($options[
'c3']) ? $options[
'c3'] :
'FF0'),
121 (isset($options[
'c4']) ? $options[
'c4'] :
'0F0'),
122 (isset($options[
'c5']) ? $options[
'c5'] :
'0FF'),
123 (isset($options[
'c6']) ? $options[
'c6'] :
'00F'),
124 (isset($options[
'c7']) ? $options[
'c7'] :
'F0F'),
125 (isset($options[
'c8']) ? $options[
'c8'] :
'FFF'),
126 (isset($options[
'c9']) ? $options[
'c9'] :
'000'),
128 foreach ($colors as $i => $color) {
129 $colors[$i] = $this->allocate_color($image, $color);
131 $this->dispatch_render_image(
132 $image, $code, $x, $y, $w, $h, $colors, $widths, $options
138 list($code, $widths, $width, $height, $x, $y, $w, $h) =
139 $this->encode_and_calculate_size($symbology, $data, $options);
140 $svg =
'<?xml version="1.0"?>';
141 $svg .=
'<svg xmlns="http://www.w3.org/2000/svg" version="1.1"';
142 $svg .=
' width="' . $width .
'" height="' . $height .
'"';
143 $svg .=
' viewBox="0 5 ' . $width .
' ' . $height .
'"><g>';
144 $bgcolor = (isset($options[
'bc']) ? $options[
'bc'] :
'white');
146 $svg .=
'<rect x="0" y="0"';
147 $svg .=
' width="' . $width .
'" height="' . $height .
'"';
148 $svg .=
' fill="' . htmlspecialchars($bgcolor) .
'"/>';
151 (isset($options[
'cs']) ? $options[
'cs'] :
''),
152 (isset($options[
'cm']) ? $options[
'cm'] :
'black'),
153 (isset($options[
'c2']) ? $options[
'c2'] :
'#FF0000'),
154 (isset($options[
'c3']) ? $options[
'c3'] :
'#FFFF00'),
155 (isset($options[
'c4']) ? $options[
'c4'] :
'#00FF00'),
156 (isset($options[
'c5']) ? $options[
'c5'] :
'#00FFFF'),
157 (isset($options[
'c6']) ? $options[
'c6'] :
'#0000FF'),
158 (isset($options[
'c7']) ? $options[
'c7'] :
'#FF00FF'),
159 (isset($options[
'c8']) ? $options[
'c8'] :
'white'),
160 (isset($options[
'c9']) ? $options[
'c9'] :
'black'),
162 $svg .= $this->dispatch_render_svg(
163 $code, $x, $y, $w, $h, $colors, $widths, $options
165 $svg .=
'</g></svg>';
171 private function encode_and_calculate_size($symbology, $data, $options) {
172 $code = $this->dispatch_encode($symbology, $data, $options);
174 (isset($options[
'wq']) ? (
int)$options[
'wq'] : 1),
175 (isset($options[
'wm']) ? (
int)$options[
'wm'] : 1),
176 (isset($options[
'ww']) ? (
int)$options[
'ww'] : 3),
177 (isset($options[
'wn']) ? (
int)$options[
'wn'] : 1),
178 (isset($options[
'w4']) ? (
int)$options[
'w4'] : 1),
179 (isset($options[
'w5']) ? (
int)$options[
'w5'] : 1),
180 (isset($options[
'w6']) ? (
int)$options[
'w6'] : 1),
181 (isset($options[
'w7']) ? (
int)$options[
'w7'] : 1),
182 (isset($options[
'w8']) ? (
int)$options[
'w8'] : 1),
183 (isset($options[
'w9']) ? (
int)$options[
'w9'] : 1),
185 $size = $this->dispatch_calculate_size($code, $widths, $options);
186 $dscale = ($code && isset($code[
'g']) && $code[
'g'] ==
'm') ? 4 : 1;
187 $scale = (isset($options[
'sf']) ? (float)$options[
'sf'] : $dscale);
188 $scalex = (isset($options[
'sx']) ? (float)$options[
'sx'] : $scale);
189 $scaley = (isset($options[
'sy']) ? (float)$options[
'sy'] : $scale);
190 $dpadding = ($code && isset($code[
'g']) && $code[
'g'] ==
'm') ? 0 : 10;
191 $padding = (isset($options[
'p']) ? (int)$options[
'p'] : $dpadding);
192 $vert = (isset($options[
'pv']) ? (int)$options[
'pv'] : $padding);
193 $horiz = (isset($options[
'ph']) ? (int)$options[
'ph'] : $padding);
194 $top = (isset($options[
'pt']) ? (int)$options[
'pt'] : $vert);
195 $left = (isset($options[
'pl']) ? (int)$options[
'pl'] : $horiz);
196 $right = (isset($options[
'pr']) ? (int)$options[
'pr'] : $horiz);
197 $bottom = (isset($options[
'pb']) ? (int)$options[
'pb'] : $vert);
198 $dwidth = ceil($size[0] * $scalex) + $left + $right;
199 $dheight = ceil($size[1] * $scaley) + $top + $bottom;
200 $iwidth = (isset($options[
'w']) ? (int)$options[
'w'] : $dwidth);
201 $iheight = (isset($options[
'h']) ? (int)$options[
'h'] : $dheight);
202 $swidth = $iwidth - $left - $right;
203 $sheight = $iheight - $top - $bottom;
205 $code, $widths, $iwidth, $iheight,
206 $left, $top, $swidth, $sheight
210 private function allocate_color($image, $color) {
211 $color = preg_replace(
'/[^0-9A-Fa-f]/',
'', $color);
212 switch (strlen($color)) {
214 $v = hexdec($color) * 17;
215 return imagecolorallocate($image, $v, $v, $v);
218 return imagecolorallocate($image, $v, $v, $v);
220 $r = hexdec(substr($color, 0, 1)) * 17;
221 $g = hexdec(substr($color, 1, 1)) * 17;
222 $b = hexdec(substr($color, 2, 1)) * 17;
223 return imagecolorallocate($image, $r, $g, $b);
225 $a = hexdec(substr($color, 0, 1)) * 17;
226 $r = hexdec(substr($color, 1, 1)) * 17;
227 $g = hexdec(substr($color, 2, 1)) * 17;
228 $b = hexdec(substr($color, 3, 1)) * 17;
229 $a = round((255 - $a) * 127 / 255);
230 return imagecolorallocatealpha($image, $r, $g, $b, $a);
232 $r = hexdec(substr($color, 0, 2));
233 $g = hexdec(substr($color, 2, 2));
234 $b = hexdec(substr($color, 4, 2));
235 return imagecolorallocate($image, $r, $g, $b);
237 $a = hexdec(substr($color, 0, 2));
238 $r = hexdec(substr($color, 2, 2));
239 $g = hexdec(substr($color, 4, 2));
240 $b = hexdec(substr($color, 6, 2));
241 $a = round((255 - $a) * 127 / 255);
242 return imagecolorallocatealpha($image, $r, $g, $b, $a);
244 return imagecolorallocatealpha($image, 0, 0, 0, 127);
250 private function dispatch_encode($symbology, $data, $options) {
251 switch (strtolower(preg_replace(
'/[^A-Za-z0-9]/',
'', $symbology))) {
252 case 'upca' :
return $this->upc_a_encode($data);
253 case 'upce' :
return $this->upc_e_encode($data);
254 case 'ean13nopad' :
return $this->ean_13_encode($data,
' ');
255 case 'ean13pad' :
return $this->ean_13_encode($data,
'>');
256 case 'ean13' :
return $this->ean_13_encode($data,
'>');
257 case 'ean8' :
return $this->ean_8_encode($data);
258 case 'code39' :
return $this->code_39_encode($data);
259 case 'code39ascii':
return $this->code_39_ascii_encode($data);
260 case 'code93' :
return $this->code_93_encode($data);
261 case 'code93ascii':
return $this->code_93_ascii_encode($data);
262 case 'code128' :
return $this->code_128_encode($data, 0,
false);
263 case 'code128a' :
return $this->code_128_encode($data, 1,
false);
264 case 'code128b' :
return $this->code_128_encode($data, 2,
false);
265 case 'code128c' :
return $this->code_128_encode($data, 3,
false);
266 case 'code128ac' :
return $this->code_128_encode($data,-1,
false);
267 case 'code128bc' :
return $this->code_128_encode($data,-2,
false);
268 case 'ean128' :
return $this->code_128_encode($data, 0,
true);
269 case 'ean128a' :
return $this->code_128_encode($data, 1,
true);
270 case 'ean128b' :
return $this->code_128_encode($data, 2,
true);
271 case 'ean128c' :
return $this->code_128_encode($data, 3,
true);
272 case 'ean128ac' :
return $this->code_128_encode($data,-1,
true);
273 case 'ean128bc' :
return $this->code_128_encode($data,-2,
true);
274 case 'codabar' :
return $this->codabar_encode($data);
275 case 'itf' :
return $this->itf_encode($data);
276 case 'itf14' :
return $this->itf_encode($data);
277 case 'qr' :
return $this->qr_encode($data, 0);
278 case 'qrl' :
return $this->qr_encode($data, 0);
279 case 'qrm' :
return $this->qr_encode($data, 1);
280 case 'qrq' :
return $this->qr_encode($data, 2);
281 case 'qrh' :
return $this->qr_encode($data, 3);
282 case 'dmtx' :
return $this->dmtx_encode($data,
false,
false);
283 case 'dmtxs' :
return $this->dmtx_encode($data,
false,
false);
284 case 'dmtxr' :
return $this->dmtx_encode($data,
true ,
false);
285 case 'gs1dmtx' :
return $this->dmtx_encode($data,
false,
true);
286 case 'gs1dmtxs' :
return $this->dmtx_encode($data,
false,
true);
287 case 'gs1dmtxr' :
return $this->dmtx_encode($data,
true ,
true);
292 private function dispatch_calculate_size($code, $widths, $options) {
293 if ($code && isset($code[
'g']) && $code[
'g']) {
294 switch ($code[
'g']) {
296 return $this->linear_calculate_size($code, $widths);
298 return $this->matrix_calculate_size($code, $widths);
304 private function dispatch_render_image(
305 $image, $code, $x, $y, $w, $h, $colors, $widths, $options
307 if ($code && isset($code[
'g']) && $code[
'g']) {
308 switch ($code[
'g']) {
310 $this->linear_render_image(
311 $image, $code, $x, $y, $w, $h,
312 $colors, $widths, $options
316 $this->matrix_render_image(
317 $image, $code, $x, $y, $w, $h,
318 $colors, $widths, $options
325 private function dispatch_render_svg(
326 $code, $x, $y, $w, $h, $colors, $widths, $options
328 if ($code && isset($code[
'g']) && $code[
'g']) {
329 switch ($code[
'g']) {
331 return $this->linear_render_svg(
332 $code, $x, $y, $w, $h,
333 $colors, $widths, $options
336 return $this->matrix_render_svg(
337 $code, $x, $y, $w, $h,
338 $colors, $widths, $options
347 private function linear_calculate_size($code, $widths) {
349 foreach ($code[
'b'] as $block) {
350 foreach ($block[
'm'] as $module) {
351 $width += $module[1] * $widths[$module[2]];
354 return array($width, 80);
357 private function linear_render_image(
358 $image, $code, $x, $y, $w, $h, $colors, $widths, $options
360 $textheight = (isset($options[
'th']) ? (int)$options[
'th'] : 10);
361 $textsize = (isset($options[
'ts']) ? (int)$options[
'ts'] : 1);
362 $textcolor = (isset($options[
'tc']) ? $options[
'tc'] :
'000');
363 $textcolor = $this->allocate_color($image, $textcolor);
365 foreach ($code[
'b'] as $block) {
366 foreach ($block[
'm'] as $module) {
367 $width += $module[1] * $widths[$module[2]];
371 $scale = $w / $width;
372 $scale = (($scale > 1) ? floor($scale) : 1);
373 $x = floor($x + ($w - $width * $scale) / 2);
376 $x = floor($x + $w / 2);
378 foreach ($code[
'b'] as $block) {
379 if (isset($block[
'l'])) {
380 $label = $block[
'l'][0];
381 $ly = (isset($block[
'l'][1]) ? (float)$block[
'l'][1] : 1);
382 $lx = (isset($block[
'l'][2]) ? (float)$block[
'l'][2] : 0.5);
383 $my = round($y + min($h, $h + ($ly - 1) * $textheight));
384 $ly = ($y + $h + $ly * $textheight);
385 $ly = round($ly - imagefontheight($textsize));
391 foreach ($block[
'm'] as $module) {
392 $mc = $colors[$module[0]];
393 $mw = $mx + $module[1] * $widths[$module[2]] * $scale;
394 imagefilledrectangle($image, $mx, $y, $mw - 1, $my - 1, $mc);
397 if (!is_null($label)) {
398 $lx = ($x + ($mx - $x) * $lx);
399 $lw = imagefontwidth($textsize) * strlen($label);
400 $lx = round($lx - $lw / 2);
401 imagestring($image, $textsize, $lx, $ly, $label, $textcolor);
407 private function linear_render_svg(
408 $code, $x, $y, $w, $h, $colors, $widths, $options
410 $textheight = (isset($options[
'th']) ? (int)$options[
'th'] : 10);
411 $textfont = (isset($options[
'tf']) ? $options[
'tf'] :
'monospace');
412 $textsize = (isset($options[
'ts']) ? (int)$options[
'ts'] : 10);
413 $textcolor = (isset($options[
'tc']) ? $options[
'tc'] :
'black');
415 foreach ($code[
'b'] as $block) {
416 foreach ($block[
'm'] as $module) {
417 $width += $module[1] * $widths[$module[2]];
421 $scale = $w / $width;
423 $scale = floor($scale);
424 $x = floor($x + ($w - $width * $scale) / 2);
428 $x = floor($x + $w / 2);
430 $tx =
'translate(' . $x .
' ' . $y .
')';
431 if ($scale != 1) $tx .=
' scale(' . $scale .
' 1)';
432 $svg =
'<g transform="' . htmlspecialchars($tx) .
'">';
434 foreach ($code[
'b'] as $block) {
435 if (isset($block[
'l'])) {
436 $label = $block[
'l'][0];
437 $ly = (isset($block[
'l'][1]) ? (float)$block[
'l'][1] : 1);
438 $lx = (isset($block[
'l'][2]) ? (float)$block[
'l'][2] : 0.5);
439 $mh = min($h, $h + ($ly - 1) * $textheight);
440 $ly = $h + $ly * $textheight;
447 foreach ($block[
'm'] as $module) {
448 $mc = htmlspecialchars($colors[$module[0]]);
449 $mw = $module[1] * $widths[$module[2]];
452 $svg .=
' x="' . $mx .
'" y="0"';
453 $svg .=
' width="' . $mw .
'"';
454 $svg .=
' height="' . $mh .
'"';
455 $svg .=
' fill="' . $mc .
'"/>';
459 if (!is_null($label)) {
460 $lx = ($x + ($mx - $x) * $lx);
462 $svg .=
' x="' . $lx .
'" y="' . $ly .
'"';
463 $svg .=
' text-anchor="middle"';
464 $svg .=
' font-family="'.htmlspecialchars($textfont).
'"';
465 $svg .=
' font-size="'.htmlspecialchars($textsize).
'"';
466 $svg .=
' fill="'.htmlspecialchars($textcolor).
'">';
467 $svg .= htmlspecialchars($label);
473 return $svg .
'</g>';
478 private function matrix_calculate_size($code, $widths) {
480 $code[
'q'][3] * $widths[0] +
481 $code[
's'][0] * $widths[1] +
482 $code[
'q'][1] * $widths[0]
485 $code[
'q'][0] * $widths[0] +
486 $code[
's'][1] * $widths[1] +
487 $code[
'q'][2] * $widths[0]
489 return array($width, $height);
492 private function matrix_render_image(
493 $image, $code, $x, $y, $w, $h, $colors, $widths, $options
495 $shape = (isset($options[
'ms']) ? strtolower($options[
'ms']) :
'');
496 $density = (isset($options[
'md']) ? (float)$options[
'md'] : 1);
497 list($width, $height) = $this->matrix_calculate_size($code, $widths);
498 if ($width && $height) {
499 $scale = min($w / $width, $h / $height);
500 $scale = (($scale > 1) ? floor($scale) : 1);
501 $x = floor($x + ($w - $width * $scale) / 2);
502 $y = floor($y + ($h - $height * $scale) / 2);
505 $x = floor($x + $w / 2);
506 $y = floor($y + $h / 2);
508 $x += $code[
'q'][3] * $widths[0] * $scale;
509 $y += $code[
'q'][0] * $widths[0] * $scale;
510 $wh = $widths[1] * $scale;
511 foreach ($code[
'b'] as $by => $row) {
512 $y1 = $y + $by * $wh;
513 foreach ($row as $bx => $color) {
514 $x1 = $x + $bx * $wh;
515 $mc = $colors[$color];
516 $this->matrix_dot_image(
517 $image, $x1, $y1, $wh, $wh, $mc, $shape, $density
523 private function matrix_render_svg(
524 $code, $x, $y, $w, $h, $colors, $widths, $options
526 $shape = (isset($options[
'ms']) ? strtolower($options[
'ms']) :
'');
527 $density = (isset($options[
'md']) ? (float)$options[
'md'] : 1);
528 list($width, $height) = $this->matrix_calculate_size($code, $widths);
529 if ($width && $height) {
530 $scale = min($w / $width, $h / $height);
531 if ($scale > 1) $scale = floor($scale);
532 $x = floor($x + ($w - $width * $scale) / 2);
533 $y = floor($y + ($h - $height * $scale) / 2);
536 $x = floor($x + $w / 2);
537 $y = floor($y + $h / 2);
539 $tx =
'translate(' . $x .
' ' . $y .
')';
540 if ($scale != 1) $tx .=
' scale(' . $scale .
' ' . $scale .
')';
541 $svg =
'<g transform="' . htmlspecialchars($tx) .
'">';
542 $x = $code[
'q'][3] * $widths[0];
543 $y = $code[
'q'][0] * $widths[0];
545 foreach ($code[
'b'] as $by => $row) {
546 $y1 = $y + $by * $wh;
547 foreach ($row as $bx => $color) {
548 $x1 = $x + $bx * $wh;
549 $mc = $colors[$color];
551 $svg .= $this->matrix_dot_svg(
552 $x1, $y1, $wh, $wh, $mc, $shape, $density
557 return $svg .
'</g>';
560 private function matrix_dot_image($image, $x, $y, $w, $h, $mc, $ms, $md) {
563 $x = floor($x + (1 - $md) * $w / 2);
564 $y = floor($y + (1 - $md) * $h / 2);
567 imagefilledrectangle($image, $x, $y, $x+$w-1, $y+$h-1, $mc);
570 $cx = floor($x + $w / 2);
571 $cy = floor($y + $h / 2);
572 $dx = ceil($w * $md);
573 $dy = ceil($h * $md);
574 imagefilledellipse($image, $cx, $cy, $dx, $dy, $mc);
577 $x = floor($x + (1 - $md) * $w / 2);
578 $y = floor($y + (1 - $md) * $h / 2);
581 imageline($image, $x, $y, $x+$w-1, $y+$h-1, $mc);
582 imageline($image, $x, $y+$h-1, $x+$w-1, $y, $mc);
587 private function matrix_dot_svg($x, $y, $w, $h, $mc, $ms, $md) {
590 $x += (1 - $md) * $w / 2;
591 $y += (1 - $md) * $h / 2;
594 $svg =
'<rect x="' . $x .
'" y="' . $y .
'"';
595 $svg .=
' width="' . $w .
'" height="' . $h .
'"';
596 $svg .=
' fill="' . $mc .
'"/>';
603 $svg =
'<ellipse cx="' . $cx .
'" cy="' . $cy .
'"';
604 $svg .=
' rx="' . $rx .
'" ry="' . $ry .
'"';
605 $svg .=
' fill="' . $mc .
'"/>';
608 $x1 = $x + (1 - $md) * $w / 2;
609 $y1 = $y + (1 - $md) * $h / 2;
610 $x2 = $x + $w - (1 - $md) * $w / 2;
611 $y2 = $y + $h - (1 - $md) * $h / 2;
612 $svg =
'<line x1="' . $x1 .
'" y1="' . $y1 .
'"';
613 $svg .=
' x2="' . $x2 .
'" y2="' . $y2 .
'"';
614 $svg .=
' stroke="' . $mc .
'"';
615 $svg .=
' stroke-width="' . ($md / 5) .
'"/>';
616 $svg .=
'<line x1="' . $x1 .
'" y1="' . $y2 .
'"';
617 $svg .=
' x2="' . $x2 .
'" y2="' . $y1 .
'"';
618 $svg .=
' stroke="' . $mc .
'"';
619 $svg .=
' stroke-width="' . ($md / 5) .
'"/>';
620 return '<g>' . $svg .
'</g>';
626 private function upc_a_encode($data) {
627 $data = $this->upc_a_normalize($data);
630 $digit = substr($data, 0, 1);
632 'm' => array(array(0, 9, 0)),
633 'l' => array($digit, 0, 1/3)
644 array(0, $this->upc_alphabet[$digit][0], 1),
645 array(1, $this->upc_alphabet[$digit][1], 1),
646 array(0, $this->upc_alphabet[$digit][2], 1),
647 array(1, $this->upc_alphabet[$digit][3], 1),
651 for ($i = 1; $i < 6; $i++) {
652 $digit = substr($data, $i, 1);
655 array(0, $this->upc_alphabet[$digit][0], 1),
656 array(1, $this->upc_alphabet[$digit][1], 1),
657 array(0, $this->upc_alphabet[$digit][2], 1),
658 array(1, $this->upc_alphabet[$digit][3], 1),
660 'l' => array($digit, 0.5, (6 - $i) / 6)
674 for ($i = 6; $i < 11; $i++) {
675 $digit = substr($data, $i, 1);
678 array(1, $this->upc_alphabet[$digit][0], 1),
679 array(0, $this->upc_alphabet[$digit][1], 1),
680 array(1, $this->upc_alphabet[$digit][2], 1),
681 array(0, $this->upc_alphabet[$digit][3], 1),
683 'l' => array($digit, 0.5, (11 - $i) / 6)
687 $digit = substr($data, 11, 1);
690 array(1, $this->upc_alphabet[$digit][0], 1),
691 array(0, $this->upc_alphabet[$digit][1], 1),
692 array(1, $this->upc_alphabet[$digit][2], 1),
693 array(0, $this->upc_alphabet[$digit][3], 1),
704 'm' => array(array(0, 9, 0)),
705 'l' => array($digit, 0, 2/3)
708 return array(
'g' =>
'l',
'b' => $blocks);
711 private function upc_e_encode($data) {
712 $data = $this->upc_e_normalize($data);
716 'm' => array(array(0, 9, 0))
726 $system = substr($data, 0, 1) & 1;
727 $check = substr($data, 7, 1);
728 $pbits = $this->upc_parity[
$check];
729 for ($i = 1; $i < 7; $i++) {
730 $digit = substr($data, $i, 1);
731 $pbit = $pbits[$i - 1] ^ $system;
734 array(0, $this->upc_alphabet[$digit][$pbit ? 3 : 0], 1),
735 array(1, $this->upc_alphabet[$digit][$pbit ? 2 : 1], 1),
736 array(0, $this->upc_alphabet[$digit][$pbit ? 1 : 2], 1),
737 array(1, $this->upc_alphabet[$digit][$pbit ? 0 : 3], 1),
739 'l' => array($digit, 0.5, (7 - $i) / 7)
754 'm' => array(array(0, 9, 0))
757 return array(
'g' =>
'l',
'b' => $blocks);
760 private function ean_13_encode($data, $pad) {
761 $data = $this->ean_13_normalize($data);
764 $system = substr($data, 0, 1);
767 $this->upc_parity[$system] :
768 array(1, 1, 1, 1, 1, 1)
771 'm' => array(array(0, 9, 0)),
772 'l' => array($system, 0.5, 1/3)
782 for ($i = 1; $i < 7; $i++) {
783 $digit = substr($data, $i, 1);
784 $pbit = $pbits[$i - 1];
787 array(0, $this->upc_alphabet[$digit][$pbit ? 0 : 3], 1),
788 array(1, $this->upc_alphabet[$digit][$pbit ? 1 : 2], 1),
789 array(0, $this->upc_alphabet[$digit][$pbit ? 2 : 1], 1),
790 array(1, $this->upc_alphabet[$digit][$pbit ? 3 : 0], 1),
792 'l' => array($digit, 0.5, (7 - $i) / 7)
806 for ($i = 7; $i < 13; $i++) {
807 $digit = substr($data, $i, 1);
810 array(1, $this->upc_alphabet[$digit][0], 1),
811 array(0, $this->upc_alphabet[$digit][1], 1),
812 array(1, $this->upc_alphabet[$digit][2], 1),
813 array(0, $this->upc_alphabet[$digit][3], 1),
815 'l' => array($digit, 0.5, (13 - $i) / 7)
827 'm' => array(array(0, 9, 0)),
828 'l' => array($pad, 0.5, 2/3)
831 return array(
'g' =>
'l',
'b' => $blocks);
834 private function ean_8_encode($data) {
835 $data = $this->ean_8_normalize($data);
839 'm' => array(array(0, 9, 0)),
840 'l' => array(
'<', 0.5, 1/3)
850 for ($i = 0; $i < 4; $i++) {
851 $digit = substr($data, $i, 1);
854 array(0, $this->upc_alphabet[$digit][0], 1),
855 array(1, $this->upc_alphabet[$digit][1], 1),
856 array(0, $this->upc_alphabet[$digit][2], 1),
857 array(1, $this->upc_alphabet[$digit][3], 1),
859 'l' => array($digit, 0.5, (4 - $i) / 5)
873 for ($i = 4; $i < 8; $i++) {
874 $digit = substr($data, $i, 1);
877 array(1, $this->upc_alphabet[$digit][0], 1),
878 array(0, $this->upc_alphabet[$digit][1], 1),
879 array(1, $this->upc_alphabet[$digit][2], 1),
880 array(0, $this->upc_alphabet[$digit][3], 1),
882 'l' => array($digit, 0.5, (8 - $i) / 5)
894 'm' => array(array(0, 9, 0)),
895 'l' => array(
'>', 0.5, 2/3)
898 return array(
'g' =>
'l',
'b' => $blocks);
901 private function upc_a_normalize($data) {
902 $data = preg_replace(
'/[^0-9*]/',
'', $data);
904 if (strlen($data) < 5) {
905 $data = str_repeat(
'0', 12);
906 }
else if (strlen($data) < 12) {
907 $system = substr($data, 0, 1);
908 $edata = substr($data, 1, -2);
909 $epattern = (int)substr($data, -2, 1);
910 $check = substr($data, -1);
912 $left = $system . substr($edata, 0, 2) . $epattern;
913 $right = substr($edata, 2) .
$check;
914 }
else if ($epattern < strlen($edata)) {
915 $left = $system . substr($edata, 0, $epattern);
916 $right = substr($edata, $epattern) .
$check;
918 $left = $system . $edata;
919 $right = $epattern .
$check;
921 $center = str_repeat(
'0', 12 - strlen($left . $right));
922 $data = $left . $center . $right;
923 }
else if (strlen($data) > 12) {
924 $left = substr($data, 0, 6);
925 $right = substr($data, -6);
926 $data = $left . $right;
929 while (($o = strrpos($data,
'*')) !==
false) {
931 for ($i = 0; $i < 12; $i++) {
932 $digit = substr($data, $i, 1);
933 $checksum += (($i % 2) ? 1 : 3) * $digit;
935 $checksum *= (($o % 2) ? 9 : 3);
936 $left = substr($data, 0, $o);
937 $center = substr($checksum, -1);
938 $right = substr($data, $o + 1);
939 $data = $left . $center . $right;
944 private function upc_e_normalize($data) {
945 $data = preg_replace(
'/[^0-9*]/',
'', $data);
948 '/^([01])([0-9][0-9][0-9][0-9][0-9][0-9])([0-9])$/',
955 '/^([01])([0-9][0-9][0-9][0-9][0-9][0-9])([*])$/',
958 $data = $this->upc_a_normalize($data);
959 return $m[1] . $m[2] . substr($data, -1);
962 $data = $this->upc_a_normalize($data);
964 '/^([01])([0-9][0-9])([0-2])0000([0-9][0-9][0-9])([0-9])$/',
967 return $m[1] . $m[2] . $m[4] . $m[3] . $m[5];
970 '/^([01])([0-9][0-9][0-9])00000([0-9][0-9])([0-9])$/',
973 return $m[1] . $m[2] . $m[3] .
'3' . $m[4];
976 '/^([01])([0-9][0-9][0-9][0-9])00000([0-9])([0-9])$/',
979 return $m[1] . $m[2] . $m[3] .
'4' . $m[4];
982 '/^([01])([0-9][0-9][0-9][0-9][0-9])0000([5-9])([0-9])$/',
985 return $m[1] . $m[2] . $m[3] . $m[4];
987 return str_repeat(
'0', 8);
990 private function ean_13_normalize($data) {
991 $data = preg_replace(
'/[^0-9*]/',
'', $data);
993 if (strlen($data) < 13) {
994 return '0' . $this->upc_a_normalize($data);
995 }
else if (strlen($data) > 13) {
996 $left = substr($data, 0, 7);
997 $right = substr($data, -6);
998 $data = $left . $right;
1001 while (($o = strrpos($data,
'*')) !==
false) {
1003 for ($i = 0; $i < 13; $i++) {
1004 $digit = substr($data, $i, 1);
1005 $checksum += (($i % 2) ? 3 : 1) * $digit;
1007 $checksum *= (($o % 2) ? 3 : 9);
1008 $left = substr($data, 0, $o);
1009 $center = substr($checksum, -1);
1010 $right = substr($data, $o + 1);
1011 $data = $left . $center . $right;
1016 private function ean_8_normalize($data) {
1017 $data = preg_replace(
'/[^0-9*]/',
'', $data);
1019 if (strlen($data) < 8) {
1020 $midpoint = floor(strlen($data) / 2);
1021 $left = substr($data, 0, $midpoint);
1022 $center = str_repeat(
'0', 8 - strlen($data));
1023 $right = substr($data, $midpoint);
1024 $data = $left . $center . $right;
1025 }
else if (strlen($data) > 8) {
1026 $left = substr($data, 0, 4);
1027 $right = substr($data, -4);
1028 $data = $left . $right;
1031 while (($o = strrpos($data,
'*')) !==
false) {
1033 for ($i = 0; $i < 8; $i++) {
1034 $digit = substr($data, $i, 1);
1035 $checksum += (($i % 2) ? 1 : 3) * $digit;
1037 $checksum *= (($o % 2) ? 9 : 3);
1038 $left = substr($data, 0, $o);
1039 $center = substr($checksum, -1);
1040 $right = substr($data, $o + 1);
1041 $data = $left . $center . $right;
1046 private $upc_alphabet = array(
1047 '0' => array(3, 2, 1, 1),
1048 '1' => array(2, 2, 2, 1),
1049 '2' => array(2, 1, 2, 2),
1050 '3' => array(1, 4, 1, 1),
1051 '4' => array(1, 1, 3, 2),
1052 '5' => array(1, 2, 3, 1),
1053 '6' => array(1, 1, 1, 4),
1054 '7' => array(1, 3, 1, 2),
1055 '8' => array(1, 2, 1, 3),
1056 '9' => array(3, 1, 1, 2),
1059 private $upc_parity = array(
1060 '0' => array(1, 1, 1, 0, 0, 0),
1061 '1' => array(1, 1, 0, 1, 0, 0),
1062 '2' => array(1, 1, 0, 0, 1, 0),
1063 '3' => array(1, 1, 0, 0, 0, 1),
1064 '4' => array(1, 0, 1, 1, 0, 0),
1065 '5' => array(1, 0, 0, 1, 1, 0),
1066 '6' => array(1, 0, 0, 0, 1, 1),
1067 '7' => array(1, 0, 1, 0, 1, 0),
1068 '8' => array(1, 0, 1, 0, 0, 1),
1069 '9' => array(1, 0, 0, 1, 0, 1),
1074 private function code_39_encode($data) {
1075 $data = strtoupper(preg_replace(
'/[^0-9A-Za-z%$\/+ .-]/',
'', $data));
1080 array(1, 1, 1), array(0, 1, 2), array(1, 1, 1),
1081 array(0, 1, 1), array(1, 1, 2), array(0, 1, 1),
1082 array(1, 1, 2), array(0, 1, 1), array(1, 1, 1),
1087 for ($i = 0, $n = strlen($data); $i < $n; $i++) {
1089 'm' => array(array(0, 1, 3))
1091 $char = substr($data, $i, 1);
1092 $block = $this->code_39_alphabet[$char];
1095 array(1, 1, $block[0]),
1096 array(0, 1, $block[1]),
1097 array(1, 1, $block[2]),
1098 array(0, 1, $block[3]),
1099 array(1, 1, $block[4]),
1100 array(0, 1, $block[5]),
1101 array(1, 1, $block[6]),
1102 array(0, 1, $block[7]),
1103 array(1, 1, $block[8]),
1109 'm' => array(array(0, 1, 3))
1114 array(1, 1, 1), array(0, 1, 2), array(1, 1, 1),
1115 array(0, 1, 1), array(1, 1, 2), array(0, 1, 1),
1116 array(1, 1, 2), array(0, 1, 1), array(1, 1, 1),
1121 return array(
'g' =>
'l',
'b' => $blocks);
1124 private function code_39_ascii_encode($data) {
1127 $modules[] = array(1, 1, 1);
1128 $modules[] = array(0, 1, 2);
1129 $modules[] = array(1, 1, 1);
1130 $modules[] = array(0, 1, 1);
1131 $modules[] = array(1, 1, 2);
1132 $modules[] = array(0, 1, 1);
1133 $modules[] = array(1, 1, 2);
1134 $modules[] = array(0, 1, 1);
1135 $modules[] = array(1, 1, 1);
1138 for ($i = 0, $n = strlen($data); $i < $n; $i++) {
1139 $char = substr($data, $i, 1);
1142 if ($ch < 32 || $ch >= 127) {
1147 $ch = $this->code_39_asciibet[$ch];
1148 for ($j = 0, $m = strlen($ch); $j < $m; $j++) {
1149 $c = substr($ch, $j, 1);
1150 $b = $this->code_39_alphabet[$c];
1151 $modules[] = array(0, 1, 3);
1152 $modules[] = array(1, 1, $b[0]);
1153 $modules[] = array(0, 1, $b[1]);
1154 $modules[] = array(1, 1, $b[2]);
1155 $modules[] = array(0, 1, $b[3]);
1156 $modules[] = array(1, 1, $b[4]);
1157 $modules[] = array(0, 1, $b[5]);
1158 $modules[] = array(1, 1, $b[6]);
1159 $modules[] = array(0, 1, $b[7]);
1160 $modules[] = array(1, 1, $b[8]);
1164 $modules[] = array(0, 1, 3);
1166 $modules[] = array(1, 1, 1);
1167 $modules[] = array(0, 1, 2);
1168 $modules[] = array(1, 1, 1);
1169 $modules[] = array(0, 1, 1);
1170 $modules[] = array(1, 1, 2);
1171 $modules[] = array(0, 1, 1);
1172 $modules[] = array(1, 1, 2);
1173 $modules[] = array(0, 1, 1);
1174 $modules[] = array(1, 1, 1);
1176 $blocks = array(array(
'm' => $modules,
'l' => array($label)));
1177 return array(
'g' =>
'l',
'b' => $blocks);
1180 private function code_93_encode($data) {
1181 $data = strtoupper(preg_replace(
'/[^0-9A-Za-z%+\/$ .-]/',
'', $data));
1184 $modules[] = array(1, 1, 1);
1185 $modules[] = array(0, 1, 1);
1186 $modules[] = array(1, 1, 1);
1187 $modules[] = array(0, 1, 1);
1188 $modules[] = array(1, 4, 1);
1189 $modules[] = array(0, 1, 1);
1192 for ($i = 0, $n = strlen($data); $i < $n; $i++) {
1193 $char = substr($data, $i, 1);
1194 $block = $this->code_93_alphabet[$char];
1195 $modules[] = array(1, $block[0], 1);
1196 $modules[] = array(0, $block[1], 1);
1197 $modules[] = array(1, $block[2], 1);
1198 $modules[] = array(0, $block[3], 1);
1199 $modules[] = array(1, $block[4], 1);
1200 $modules[] = array(0, $block[5], 1);
1201 $values[] = $block[6];
1204 for ($i = 0; $i < 2; $i++) {
1211 $checksum += $weight * $values[
$index];
1213 $weight %= ($i ? 15 : 20);
1215 $values[] = $checksum;
1217 $alphabet = array_values($this->code_93_alphabet);
1218 for ($i = count($values) - 2, $n = count($values); $i < $n; $i++) {
1219 $block = $alphabet[$values[$i]];
1220 $modules[] = array(1, $block[0], 1);
1221 $modules[] = array(0, $block[1], 1);
1222 $modules[] = array(1, $block[2], 1);
1223 $modules[] = array(0, $block[3], 1);
1224 $modules[] = array(1, $block[4], 1);
1225 $modules[] = array(0, $block[5], 1);
1228 $modules[] = array(1, 1, 1);
1229 $modules[] = array(0, 1, 1);
1230 $modules[] = array(1, 1, 1);
1231 $modules[] = array(0, 1, 1);
1232 $modules[] = array(1, 4, 1);
1233 $modules[] = array(0, 1, 1);
1234 $modules[] = array(1, 1, 1);
1236 $blocks = array(array(
'm' => $modules,
'l' => array($data)));
1237 return array(
'g' =>
'l',
'b' => $blocks);
1240 private function code_93_ascii_encode($data) {
1243 $modules[] = array(1, 1, 1);
1244 $modules[] = array(0, 1, 1);
1245 $modules[] = array(1, 1, 1);
1246 $modules[] = array(0, 1, 1);
1247 $modules[] = array(1, 4, 1);
1248 $modules[] = array(0, 1, 1);
1252 for ($i = 0, $n = strlen($data); $i < $n; $i++) {
1253 $char = substr($data, $i, 1);
1256 if ($ch < 32 || $ch >= 127) {
1261 $ch = $this->code_93_asciibet[$ch];
1262 for ($j = 0, $m = strlen($ch); $j < $m; $j++) {
1263 $c = substr($ch, $j, 1);
1264 $b = $this->code_93_alphabet[$c];
1265 $modules[] = array(1, $b[0], 1);
1266 $modules[] = array(0, $b[1], 1);
1267 $modules[] = array(1, $b[2], 1);
1268 $modules[] = array(0, $b[3], 1);
1269 $modules[] = array(1, $b[4], 1);
1270 $modules[] = array(0, $b[5], 1);
1276 for ($i = 0; $i < 2; $i++) {
1283 $checksum += $weight * $values[
$index];
1285 $weight %= ($i ? 15 : 20);
1287 $values[] = $checksum;
1289 $alphabet = array_values($this->code_93_alphabet);
1290 for ($i = count($values) - 2, $n = count($values); $i < $n; $i++) {
1291 $block = $alphabet[$values[$i]];
1292 $modules[] = array(1, $block[0], 1);
1293 $modules[] = array(0, $block[1], 1);
1294 $modules[] = array(1, $block[2], 1);
1295 $modules[] = array(0, $block[3], 1);
1296 $modules[] = array(1, $block[4], 1);
1297 $modules[] = array(0, $block[5], 1);
1300 $modules[] = array(1, 1, 1);
1301 $modules[] = array(0, 1, 1);
1302 $modules[] = array(1, 1, 1);
1303 $modules[] = array(0, 1, 1);
1304 $modules[] = array(1, 4, 1);
1305 $modules[] = array(0, 1, 1);
1306 $modules[] = array(1, 1, 1);
1308 $blocks = array(array(
'm' => $modules,
'l' => array($label)));
1309 return array(
'g' =>
'l',
'b' => $blocks);
1312 private $code_39_alphabet = array(
1313 '1' => array(2, 1, 1, 2, 1, 1, 1, 1, 2),
1314 '2' => array(1, 1, 2, 2, 1, 1, 1, 1, 2),
1315 '3' => array(2, 1, 2, 2, 1, 1, 1, 1, 1),
1316 '4' => array(1, 1, 1, 2, 2, 1, 1, 1, 2),
1317 '5' => array(2, 1, 1, 2, 2, 1, 1, 1, 1),
1318 '6' => array(1, 1, 2, 2, 2, 1, 1, 1, 1),
1319 '7' => array(1, 1, 1, 2, 1, 1, 2, 1, 2),
1320 '8' => array(2, 1, 1, 2, 1, 1, 2, 1, 1),
1321 '9' => array(1, 1, 2, 2, 1, 1, 2, 1, 1),
1322 '0' => array(1, 1, 1, 2, 2, 1, 2, 1, 1),
1323 'A' => array(2, 1, 1, 1, 1, 2, 1, 1, 2),
1324 'B' => array(1, 1, 2, 1, 1, 2, 1, 1, 2),
1325 'C' => array(2, 1, 2, 1, 1, 2, 1, 1, 1),
1326 'D' => array(1, 1, 1, 1, 2, 2, 1, 1, 2),
1327 'E' => array(2, 1, 1, 1, 2, 2, 1, 1, 1),
1328 'F' => array(1, 1, 2, 1, 2, 2, 1, 1, 1),
1329 'G' => array(1, 1, 1, 1, 1, 2, 2, 1, 2),
1330 'H' => array(2, 1, 1, 1, 1, 2, 2, 1, 1),
1331 'I' => array(1, 1, 2, 1, 1, 2, 2, 1, 1),
1332 'J' => array(1, 1, 1, 1, 2, 2, 2, 1, 1),
1333 'K' => array(2, 1, 1, 1, 1, 1, 1, 2, 2),
1334 'L' => array(1, 1, 2, 1, 1, 1, 1, 2, 2),
1335 'M' => array(2, 1, 2, 1, 1, 1, 1, 2, 1),
1336 'N' => array(1, 1, 1, 1, 2, 1, 1, 2, 2),
1337 'O' => array(2, 1, 1, 1, 2, 1, 1, 2, 1),
1338 'P' => array(1, 1, 2, 1, 2, 1, 1, 2, 1),
1339 'Q' => array(1, 1, 1, 1, 1, 1, 2, 2, 2),
1340 'R' => array(2, 1, 1, 1, 1, 1, 2, 2, 1),
1341 'S' => array(1, 1, 2, 1, 1, 1, 2, 2, 1),
1342 'T' => array(1, 1, 1, 1, 2, 1, 2, 2, 1),
1343 'U' => array(2, 2, 1, 1, 1, 1, 1, 1, 2),
1344 'V' => array(1, 2, 2, 1, 1, 1, 1, 1, 2),
1345 'W' => array(2, 2, 2, 1, 1, 1, 1, 1, 1),
1346 'X' => array(1, 2, 1, 1, 2, 1, 1, 1, 2),
1347 'Y' => array(2, 2, 1, 1, 2, 1, 1, 1, 1),
1348 'Z' => array(1, 2, 2, 1, 2, 1, 1, 1, 1),
1349 '-' => array(1, 2, 1, 1, 1, 1, 2, 1, 2),
1350 '.' => array(2, 2, 1, 1, 1, 1, 2, 1, 1),
1351 ' ' => array(1, 2, 2, 1, 1, 1, 2, 1, 1),
1352 '*' => array(1, 2, 1, 1, 2, 1, 2, 1, 1),
1353 '+' => array(1, 2, 1, 1, 1, 2, 1, 2, 1),
1354 '/' => array(1, 2, 1, 2, 1, 1, 1, 2, 1),
1355 '$' => array(1, 2, 1, 2, 1, 2, 1, 1, 1),
1356 '%' => array(1, 1, 1, 2, 1, 2, 1, 2, 1),
1359 private $code_39_asciibet = array(
1360 '%U',
'$A',
'$B',
'$C',
'$D',
'$E',
'$F',
'$G',
1361 '$H',
'$I',
'$J',
'$K',
'$L',
'$M',
'$N',
'$O',
1362 '$P',
'$Q',
'$R',
'$S',
'$T',
'$U',
'$V',
'$W',
1363 '$X',
'$Y',
'$Z',
'%A',
'%B',
'%C',
'%D',
'%E',
1364 ' ' ,
'/A',
'/B',
'/C',
'/D',
'/E',
'/F',
'/G',
1365 '/H',
'/I',
'/J',
'/K',
'/L',
'-' ,
'.' ,
'/O',
1366 '0' ,
'1' ,
'2' ,
'3' ,
'4' ,
'5' ,
'6' ,
'7' ,
1367 '8' ,
'9' ,
'/Z',
'%F',
'%G',
'%H',
'%I',
'%J',
1368 '%V',
'A' ,
'B' ,
'C' ,
'D' ,
'E' ,
'F' ,
'G' ,
1369 'H' ,
'I' ,
'J' ,
'K' ,
'L' ,
'M' ,
'N' ,
'O' ,
1370 'P' ,
'Q' ,
'R' ,
'S' ,
'T' ,
'U' ,
'V' ,
'W' ,
1371 'X' ,
'Y' ,
'Z' ,
'%K',
'%L',
'%M',
'%N',
'%O',
1372 '%W',
'+A',
'+B',
'+C',
'+D',
'+E',
'+F',
'+G',
1373 '+H',
'+I',
'+J',
'+K',
'+L',
'+M',
'+N',
'+O',
1374 '+P',
'+Q',
'+R',
'+S',
'+T',
'+U',
'+V',
'+W',
1375 '+X',
'+Y',
'+Z',
'%P',
'%Q',
'%R',
'%S',
'%T',
1378 private $code_93_alphabet = array(
1379 '0' => array(1, 3, 1, 1, 1, 2, 0),
1380 '1' => array(1, 1, 1, 2, 1, 3, 1),
1381 '2' => array(1, 1, 1, 3, 1, 2, 2),
1382 '3' => array(1, 1, 1, 4, 1, 1, 3),
1383 '4' => array(1, 2, 1, 1, 1, 3, 4),
1384 '5' => array(1, 2, 1, 2, 1, 2, 5),
1385 '6' => array(1, 2, 1, 3, 1, 1, 6),
1386 '7' => array(1, 1, 1, 1, 1, 4, 7),
1387 '8' => array(1, 3, 1, 2, 1, 1, 8),
1388 '9' => array(1, 4, 1, 1, 1, 1, 9),
1389 'A' => array(2, 1, 1, 1, 1, 3, 10),
1390 'B' => array(2, 1, 1, 2, 1, 2, 11),
1391 'C' => array(2, 1, 1, 3, 1, 1, 12),
1392 'D' => array(2, 2, 1, 1, 1, 2, 13),
1393 'E' => array(2, 2, 1, 2, 1, 1, 14),
1394 'F' => array(2, 3, 1, 1, 1, 1, 15),
1395 'G' => array(1, 1, 2, 1, 1, 3, 16),
1396 'H' => array(1, 1, 2, 2, 1, 2, 17),
1397 'I' => array(1, 1, 2, 3, 1, 1, 18),
1398 'J' => array(1, 2, 2, 1, 1, 2, 19),
1399 'K' => array(1, 3, 2, 1, 1, 1, 20),
1400 'L' => array(1, 1, 1, 1, 2, 3, 21),
1401 'M' => array(1, 1, 1, 2, 2, 2, 22),
1402 'N' => array(1, 1, 1, 3, 2, 1, 23),
1403 'O' => array(1, 2, 1, 1, 2, 2, 24),
1404 'P' => array(1, 3, 1, 1, 2, 1, 25),
1405 'Q' => array(2, 1, 2, 1, 1, 2, 26),
1406 'R' => array(2, 1, 2, 2, 1, 1, 27),
1407 'S' => array(2, 1, 1, 1, 2, 2, 28),
1408 'T' => array(2, 1, 1, 2, 2, 1, 29),
1409 'U' => array(2, 2, 1, 1, 2, 1, 30),
1410 'V' => array(2, 2, 2, 1, 1, 1, 31),
1411 'W' => array(1, 1, 2, 1, 2, 2, 32),
1412 'X' => array(1, 1, 2, 2, 2, 1, 33),
1413 'Y' => array(1, 2, 2, 1, 2, 1, 34),
1414 'Z' => array(1, 2, 3, 1, 1, 1, 35),
1415 '-' => array(1, 2, 1, 1, 3, 1, 36),
1416 '.' => array(3, 1, 1, 1, 1, 2, 37),
1417 ' ' => array(3, 1, 1, 2, 1, 1, 38),
1418 '$' => array(3, 2, 1, 1, 1, 1, 39),
1419 '/' => array(1, 1, 2, 1, 3, 1, 40),
1420 '+' => array(1, 1, 3, 1, 2, 1, 41),
1421 '%' => array(2, 1, 1, 1, 3, 1, 42),
1422 '#' => array(1, 2, 1, 2, 2, 1, 43),
1423 '&' => array(3, 1, 2, 1, 1, 1, 44),
1424 '|' => array(3, 1, 1, 1, 2, 1, 45),
1425 '=' => array(1, 2, 2, 2, 1, 1, 46),
1426 '*' => array(1, 1, 1, 1, 4, 1, 0),
1429 private $code_93_asciibet = array(
1430 '&U',
'#A',
'#B',
'#C',
'#D',
'#E',
'#F',
'#G',
1431 '#H',
'#I',
'#J',
'#K',
'#L',
'#M',
'#N',
'#O',
1432 '#P',
'#Q',
'#R',
'#S',
'#T',
'#U',
'#V',
'#W',
1433 '#X',
'#Y',
'#Z',
'&A',
'&B',
'&C',
'&D',
'&E',
1434 ' ' ,
'|A',
'|B',
'|C',
'$' ,
'%' ,
'|F',
'|G',
1435 '|H',
'|I',
'|J',
'+' ,
'|L',
'-' ,
'.' ,
'/' ,
1436 '0' ,
'1' ,
'2' ,
'3' ,
'4' ,
'5' ,
'6' ,
'7' ,
1437 '8' ,
'9' ,
'|Z',
'&F',
'&G',
'&H',
'&I',
'&J',
1438 '&V',
'A' ,
'B' ,
'C' ,
'D' ,
'E' ,
'F' ,
'G' ,
1439 'H' ,
'I' ,
'J' ,
'K' ,
'L' ,
'M' ,
'N' ,
'O' ,
1440 'P' ,
'Q' ,
'R' ,
'S' ,
'T' ,
'U' ,
'V' ,
'W' ,
1441 'X' ,
'Y' ,
'Z' ,
'&K',
'&L',
'&M',
'&N',
'&O',
1442 '&W',
'=A',
'=B',
'=C',
'=D',
'=E',
'=F',
'=G',
1443 '=H',
'=I',
'=J',
'=K',
'=L',
'=M',
'=N',
'=O',
1444 '=P',
'=Q',
'=R',
'=S',
'=T',
'=U',
'=V',
'=W',
1445 '=X',
'=Y',
'=Z',
'&P',
'&Q',
'&R',
'&S',
'&T',
1450 private function code_128_encode($data, $dstate, $fnc1) {
1451 $data = preg_replace(
'/[\x80-\xFF]/',
'', $data);
1452 $label = preg_replace(
'/[\x00-\x1F\x7F]/',
' ', $data);
1453 $chars = $this->code_128_normalize($data, $dstate, $fnc1);
1454 $checksum = $chars[0] % 103;
1455 for ($i = 1, $n = count($chars); $i < $n; $i++) {
1456 $checksum += $i * $chars[$i];
1459 $chars[] = $checksum;
1462 $modules[] = array(0, 10, 0);
1463 foreach ($chars as $char) {
1464 $block = $this->code_128_alphabet[$char];
1465 foreach ($block as $i => $module) {
1466 $modules[] = array(($i & 1) ^ 1, $module, 1);
1469 $modules[] = array(0, 10, 0);
1470 $blocks = array(array(
'm' => $modules,
'l' => array($label)));
1471 return array(
'g' =>
'l',
'b' => $blocks);
1474 private function code_128_normalize($data, $dstate, $fnc1) {
1475 $detectcba =
'/(^[0-9]{4,}|^[0-9]{2}$)|([\x60-\x7F])|([\x00-\x1F])/';
1476 $detectc =
'/(^[0-9]{6,}|^[0-9]{4,}$)/';
1477 $detectba =
'/([\x60-\x7F])|([\x00-\x1F])/';
1478 $consumec =
'/(^[0-9]{2})/';
1479 $state = (($dstate > 0 && $dstate < 4) ? $dstate : 0);
1480 $abstate = ((abs($dstate) == 2) ? 2 : 1);
1481 $chars = array(102 + ($state ? $state : $abstate));
1482 if ($fnc1) $chars[] = 102;
1483 while (strlen($data)) {
1486 if (preg_match($detectcba, $data, $m)) {
1497 $chars = array(102 + $state);
1498 if ($fnc1) $chars[] = 102;
1501 if ($dstate <= 0 && preg_match($detectc, $data, $m)) {
1502 if (strlen($m[0]) % 2) {
1503 $data = substr($data, 1);
1504 $chars[] = 16 + substr($m[0], 0, 1);
1509 $ch = ord(substr($data, 0, 1));
1510 $data = substr($data, 1);
1512 $chars[] = $ch + 64;
1513 }
else if ($ch < 96) {
1514 $chars[] = $ch - 32;
1516 if (preg_match($detectba, $data, $m)) {
1526 $chars[] = $ch - 32;
1531 if ($dstate <= 0 && preg_match($detectc, $data, $m)) {
1532 if (strlen($m[0]) % 2) {
1533 $data = substr($data, 1);
1534 $chars[] = 16 + substr($m[0], 0, 1);
1539 $ch = ord(substr($data, 0, 1));
1540 $data = substr($data, 1);
1542 $chars[] = $ch - 32;
1544 if (preg_match($detectba, $data, $m)) {
1554 $chars[] = $ch + 64;
1559 if (preg_match($consumec, $data, $m)) {
1560 $data = substr($data, 2);
1561 $chars[] = (int)$m[0];
1563 if (preg_match($detectba, $data, $m)) {
1572 $chars[] = 102 - $state;
1580 private $code_128_alphabet = array(
1581 array(2, 1, 2, 2, 2, 2), array(2, 2, 2, 1, 2, 2),
1582 array(2, 2, 2, 2, 2, 1), array(1, 2, 1, 2, 2, 3),
1583 array(1, 2, 1, 3, 2, 2), array(1, 3, 1, 2, 2, 2),
1584 array(1, 2, 2, 2, 1, 3), array(1, 2, 2, 3, 1, 2),
1585 array(1, 3, 2, 2, 1, 2), array(2, 2, 1, 2, 1, 3),
1586 array(2, 2, 1, 3, 1, 2), array(2, 3, 1, 2, 1, 2),
1587 array(1, 1, 2, 2, 3, 2), array(1, 2, 2, 1, 3, 2),
1588 array(1, 2, 2, 2, 3, 1), array(1, 1, 3, 2, 2, 2),
1589 array(1, 2, 3, 1, 2, 2), array(1, 2, 3, 2, 2, 1),
1590 array(2, 2, 3, 2, 1, 1), array(2, 2, 1, 1, 3, 2),
1591 array(2, 2, 1, 2, 3, 1), array(2, 1, 3, 2, 1, 2),
1592 array(2, 2, 3, 1, 1, 2), array(3, 1, 2, 1, 3, 1),
1593 array(3, 1, 1, 2, 2, 2), array(3, 2, 1, 1, 2, 2),
1594 array(3, 2, 1, 2, 2, 1), array(3, 1, 2, 2, 1, 2),
1595 array(3, 2, 2, 1, 1, 2), array(3, 2, 2, 2, 1, 1),
1596 array(2, 1, 2, 1, 2, 3), array(2, 1, 2, 3, 2, 1),
1597 array(2, 3, 2, 1, 2, 1), array(1, 1, 1, 3, 2, 3),
1598 array(1, 3, 1, 1, 2, 3), array(1, 3, 1, 3, 2, 1),
1599 array(1, 1, 2, 3, 1, 3), array(1, 3, 2, 1, 1, 3),
1600 array(1, 3, 2, 3, 1, 1), array(2, 1, 1, 3, 1, 3),
1601 array(2, 3, 1, 1, 1, 3), array(2, 3, 1, 3, 1, 1),
1602 array(1, 1, 2, 1, 3, 3), array(1, 1, 2, 3, 3, 1),
1603 array(1, 3, 2, 1, 3, 1), array(1, 1, 3, 1, 2, 3),
1604 array(1, 1, 3, 3, 2, 1), array(1, 3, 3, 1, 2, 1),
1605 array(3, 1, 3, 1, 2, 1), array(2, 1, 1, 3, 3, 1),
1606 array(2, 3, 1, 1, 3, 1), array(2, 1, 3, 1, 1, 3),
1607 array(2, 1, 3, 3, 1, 1), array(2, 1, 3, 1, 3, 1),
1608 array(3, 1, 1, 1, 2, 3), array(3, 1, 1, 3, 2, 1),
1609 array(3, 3, 1, 1, 2, 1), array(3, 1, 2, 1, 1, 3),
1610 array(3, 1, 2, 3, 1, 1), array(3, 3, 2, 1, 1, 1),
1611 array(3, 1, 4, 1, 1, 1), array(2, 2, 1, 4, 1, 1),
1612 array(4, 3, 1, 1, 1, 1), array(1, 1, 1, 2, 2, 4),
1613 array(1, 1, 1, 4, 2, 2), array(1, 2, 1, 1, 2, 4),
1614 array(1, 2, 1, 4, 2, 1), array(1, 4, 1, 1, 2, 2),
1615 array(1, 4, 1, 2, 2, 1), array(1, 1, 2, 2, 1, 4),
1616 array(1, 1, 2, 4, 1, 2), array(1, 2, 2, 1, 1, 4),
1617 array(1, 2, 2, 4, 1, 1), array(1, 4, 2, 1, 1, 2),
1618 array(1, 4, 2, 2, 1, 1), array(2, 4, 1, 2, 1, 1),
1619 array(2, 2, 1, 1, 1, 4), array(4, 1, 3, 1, 1, 1),
1620 array(2, 4, 1, 1, 1, 2), array(1, 3, 4, 1, 1, 1),
1621 array(1, 1, 1, 2, 4, 2), array(1, 2, 1, 1, 4, 2),
1622 array(1, 2, 1, 2, 4, 1), array(1, 1, 4, 2, 1, 2),
1623 array(1, 2, 4, 1, 1, 2), array(1, 2, 4, 2, 1, 1),
1624 array(4, 1, 1, 2, 1, 2), array(4, 2, 1, 1, 1, 2),
1625 array(4, 2, 1, 2, 1, 1), array(2, 1, 2, 1, 4, 1),
1626 array(2, 1, 4, 1, 2, 1), array(4, 1, 2, 1, 2, 1),
1627 array(1, 1, 1, 1, 4, 3), array(1, 1, 1, 3, 4, 1),
1628 array(1, 3, 1, 1, 4, 1), array(1, 1, 4, 1, 1, 3),
1629 array(1, 1, 4, 3, 1, 1), array(4, 1, 1, 1, 1, 3),
1630 array(4, 1, 1, 3, 1, 1), array(1, 1, 3, 1, 4, 1),
1631 array(1, 1, 4, 1, 3, 1), array(3, 1, 1, 1, 4, 1),
1632 array(4, 1, 1, 1, 3, 1), array(2, 1, 1, 4, 1, 2),
1633 array(2, 1, 1, 2, 1, 4), array(2, 1, 1, 2, 3, 2),
1634 array(2, 3, 3, 1, 1, 1, 2)
1639 private function codabar_encode($data) {
1640 $data = strtoupper(preg_replace(
1641 '/[^0-9ABCDENTabcdent*.\/:+$-]/',
'', $data
1644 for ($i = 0, $n = strlen($data); $i < $n; $i++) {
1647 'm' => array(array(0, 1, 3))
1650 $char = substr($data, $i, 1);
1651 $block = $this->codabar_alphabet[$char];
1654 array(1, 1, $block[0]),
1655 array(0, 1, $block[1]),
1656 array(1, 1, $block[2]),
1657 array(0, 1, $block[3]),
1658 array(1, 1, $block[4]),
1659 array(0, 1, $block[5]),
1660 array(1, 1, $block[6]),
1665 return array(
'g' =>
'l',
'b' => $blocks);
1668 private $codabar_alphabet = array(
1669 '0' => array(1, 1, 1, 1, 1, 2, 2),
1670 '1' => array(1, 1, 1, 1, 2, 2, 1),
1671 '4' => array(1, 1, 2, 1, 1, 2, 1),
1672 '5' => array(2, 1, 1, 1, 1, 2, 1),
1673 '2' => array(1, 1, 1, 2, 1, 1, 2),
1674 '-' => array(1, 1, 1, 2, 2, 1, 1),
1675 '$' => array(1, 1, 2, 2, 1, 1, 1),
1676 '9' => array(2, 1, 1, 2, 1, 1, 1),
1677 '6' => array(1, 2, 1, 1, 1, 1, 2),
1678 '7' => array(1, 2, 1, 1, 2, 1, 1),
1679 '8' => array(1, 2, 2, 1, 1, 1, 1),
1680 '3' => array(2, 2, 1, 1, 1, 1, 1),
1681 'C' => array(1, 1, 1, 2, 1, 2, 2),
1682 'D' => array(1, 1, 1, 2, 2, 2, 1),
1683 'A' => array(1, 1, 2, 2, 1, 2, 1),
1684 'B' => array(1, 2, 1, 2, 1, 1, 2),
1685 '*' => array(1, 1, 1, 2, 1, 2, 2),
1686 'E' => array(1, 1, 1, 2, 2, 2, 1),
1687 'T' => array(1, 1, 2, 2, 1, 2, 1),
1688 'N' => array(1, 2, 1, 2, 1, 1, 2),
1689 '.' => array(2, 1, 2, 1, 2, 1, 1),
1690 '/' => array(2, 1, 2, 1, 1, 1, 2),
1691 ':' => array(2, 1, 1, 1, 2, 1, 2),
1692 '+' => array(1, 1, 2, 1, 2, 1, 2),
1697 private function itf_encode($data) {
1698 $data = preg_replace(
'/[^0-9]/',
'', $data);
1699 if (strlen($data) % 2) $data =
'0' . $data;
1703 'm' => array(array(0, 10, 0))
1714 for ($i = 0, $n = strlen($data); $i < $n; $i += 2) {
1715 $c1 = substr($data, $i, 1);
1716 $c2 = substr($data, $i+1, 1);
1717 $b1 = $this->itf_alphabet[$c1];
1718 $b2 = $this->itf_alphabet[$c2];
1721 array(1, 1, $b1[0]),
1722 array(0, 1, $b2[0]),
1723 array(1, 1, $b1[1]),
1724 array(0, 1, $b2[1]),
1725 array(1, 1, $b1[2]),
1726 array(0, 1, $b2[2]),
1727 array(1, 1, $b1[3]),
1728 array(0, 1, $b2[3]),
1729 array(1, 1, $b1[4]),
1730 array(0, 1, $b2[4]),
1732 'l' => array($c1 . $c2)
1744 'm' => array(array(0, 10, 0))
1747 return array(
'g' =>
'l',
'b' => $blocks);
1750 private $itf_alphabet = array(
1751 '0' => array(1, 1, 2, 2, 1),
1752 '1' => array(2, 1, 1, 1, 2),
1753 '2' => array(1, 2, 1, 1, 2),
1754 '3' => array(2, 2, 1, 1, 1),
1755 '4' => array(1, 1, 2, 1, 2),
1756 '5' => array(2, 1, 2, 1, 1),
1757 '6' => array(1, 2, 2, 1, 1),
1758 '7' => array(1, 1, 1, 2, 2),
1759 '8' => array(2, 1, 1, 2, 1),
1760 '9' => array(1, 2, 1, 2, 1),
1765 private function qr_encode($data, $ecl) {
1766 list($mode, $vers, $ec, $data) = $this->qr_encode_data($data, $ecl);
1767 $data = $this->qr_encode_ec($data, $ec, $vers);
1768 list($size, $mtx) = $this->qr_create_matrix($vers, $data);
1769 list($mask, $mtx) = $this->qr_apply_best_mask($mtx, $size);
1770 $mtx = $this->qr_finalize_matrix($mtx, $size, $ecl, $mask, $vers);
1773 'q' => array(4, 4, 4, 4),
1774 's' => array($size, $size),
1779 private function qr_encode_data($data, $ecl) {
1780 $mode = $this->qr_detect_mode($data);
1781 $version = $this->qr_detect_version($data, $mode, $ecl);
1782 $version_group = (($version < 10) ? 0 : (($version < 27) ? 1 : 2));
1783 $ec_params = $this->qr_ec_params[($version - 1) * 4 + $ecl];
1785 $max_chars = $this->qr_capacity[$version - 1][$ecl][$mode];
1786 if ($mode == 3) $max_chars <<= 1;
1787 $data = substr($data, 0, $max_chars);
1791 $code = $this->qr_encode_numeric($data, $version_group);
1794 $code = $this->qr_encode_alphanumeric($data, $version_group);
1797 $code = $this->qr_encode_binary($data, $version_group);
1800 $code = $this->qr_encode_kanji($data, $version_group);
1803 for ($i = 0; $i < 4; $i++) $code[] = 0;
1804 while (count($code) % 8) $code[] = 0;
1807 for ($i = 0, $n = count($code); $i < $n; $i += 8) {
1809 if ($code[$i + 0]) $byte |= 0x80;
1810 if ($code[$i + 1]) $byte |= 0x40;
1811 if ($code[$i + 2]) $byte |= 0x20;
1812 if ($code[$i + 3]) $byte |= 0x10;
1813 if ($code[$i + 4]) $byte |= 0x08;
1814 if ($code[$i + 5]) $byte |= 0x04;
1815 if ($code[$i + 6]) $byte |= 0x02;
1816 if ($code[$i + 7]) $byte |= 0x01;
1820 $i = count($data), $a = 1, $n = $ec_params[0];
1821 $i < $n; $i++, $a ^= 1
1823 $data[] = $a ? 236 : 17;
1826 return array($mode, $version, $ec_params, $data);
1829 private function qr_detect_mode($data) {
1830 $numeric =
'/^[0-9]*$/';
1831 $alphanumeric =
'/^[0-9A-Z .\/:$%*+-]*$/';
1832 $kanji =
'/^([\x81-\x9F\xE0-\xEA][\x40-\xFC]|[\xEB][\x40-\xBF])*$/';
1833 if (preg_match($numeric, $data))
return 0;
1834 if (preg_match($alphanumeric, $data))
return 1;
1835 if (preg_match($kanji, $data))
return 3;
1839 private function qr_detect_version($data, $mode, $ecl) {
1840 $length = strlen($data);
1841 if ($mode == 3) $length >>= 1;
1842 for ($v = 0; $v < 40; $v++) {
1843 if ($length <= $this->qr_capacity[$v][$ecl][$mode]) {
1850 private function qr_encode_numeric($data, $version_group) {
1851 $code = array(0, 0, 0, 1);
1852 $length = strlen($data);
1853 switch ($version_group) {
1855 $code[] = $length & 0x2000;
1856 $code[] = $length & 0x1000;
1858 $code[] = $length & 0x0800;
1859 $code[] = $length & 0x0400;
1861 $code[] = $length & 0x0200;
1862 $code[] = $length & 0x0100;
1863 $code[] = $length & 0x0080;
1864 $code[] = $length & 0x0040;
1865 $code[] = $length & 0x0020;
1866 $code[] = $length & 0x0010;
1867 $code[] = $length & 0x0008;
1868 $code[] = $length & 0x0004;
1869 $code[] = $length & 0x0002;
1870 $code[] = $length & 0x0001;
1872 for ($i = 0; $i < $length; $i += 3) {
1873 $group = substr($data, $i, 3);
1874 switch (strlen($group)) {
1876 $code[] = $group & 0x200;
1877 $code[] = $group & 0x100;
1878 $code[] = $group & 0x080;
1880 $code[] = $group & 0x040;
1881 $code[] = $group & 0x020;
1882 $code[] = $group & 0x010;
1884 $code[] = $group & 0x008;
1885 $code[] = $group & 0x004;
1886 $code[] = $group & 0x002;
1887 $code[] = $group & 0x001;
1893 private function qr_encode_alphanumeric($data, $version_group) {
1894 $alphabet =
'0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ $%*+-./:';
1895 $code = array(0, 0, 1, 0);
1896 $length = strlen($data);
1897 switch ($version_group) {
1899 $code[] = $length & 0x1000;
1900 $code[] = $length & 0x0800;
1902 $code[] = $length & 0x0400;
1903 $code[] = $length & 0x0200;
1905 $code[] = $length & 0x0100;
1906 $code[] = $length & 0x0080;
1907 $code[] = $length & 0x0040;
1908 $code[] = $length & 0x0020;
1909 $code[] = $length & 0x0010;
1910 $code[] = $length & 0x0008;
1911 $code[] = $length & 0x0004;
1912 $code[] = $length & 0x0002;
1913 $code[] = $length & 0x0001;
1915 for ($i = 0; $i < $length; $i += 2) {
1916 $group = substr($data, $i, 2);
1917 if (strlen($group) > 1) {
1918 $c1 = strpos($alphabet, substr($group, 0, 1));
1919 $c2 = strpos($alphabet, substr($group, 1, 1));
1920 $ch = $c1 * 45 + $c2;
1921 $code[] = $ch & 0x400;
1922 $code[] = $ch & 0x200;
1923 $code[] = $ch & 0x100;
1924 $code[] = $ch & 0x080;
1925 $code[] = $ch & 0x040;
1926 $code[] = $ch & 0x020;
1927 $code[] = $ch & 0x010;
1928 $code[] = $ch & 0x008;
1929 $code[] = $ch & 0x004;
1930 $code[] = $ch & 0x002;
1931 $code[] = $ch & 0x001;
1933 $ch = strpos($alphabet, $group);
1934 $code[] = $ch & 0x020;
1935 $code[] = $ch & 0x010;
1936 $code[] = $ch & 0x008;
1937 $code[] = $ch & 0x004;
1938 $code[] = $ch & 0x002;
1939 $code[] = $ch & 0x001;
1945 private function qr_encode_binary($data, $version_group) {
1946 $code = array(0, 1, 0, 0);
1947 $length = strlen($data);
1948 switch ($version_group) {
1951 $code[] = $length & 0x8000;
1952 $code[] = $length & 0x4000;
1953 $code[] = $length & 0x2000;
1954 $code[] = $length & 0x1000;
1955 $code[] = $length & 0x0800;
1956 $code[] = $length & 0x0400;
1957 $code[] = $length & 0x0200;
1958 $code[] = $length & 0x0100;
1960 $code[] = $length & 0x0080;
1961 $code[] = $length & 0x0040;
1962 $code[] = $length & 0x0020;
1963 $code[] = $length & 0x0010;
1964 $code[] = $length & 0x0008;
1965 $code[] = $length & 0x0004;
1966 $code[] = $length & 0x0002;
1967 $code[] = $length & 0x0001;
1969 for ($i = 0; $i < $length; $i++) {
1970 $ch = ord(substr($data, $i, 1));
1971 $code[] = $ch & 0x80;
1972 $code[] = $ch & 0x40;
1973 $code[] = $ch & 0x20;
1974 $code[] = $ch & 0x10;
1975 $code[] = $ch & 0x08;
1976 $code[] = $ch & 0x04;
1977 $code[] = $ch & 0x02;
1978 $code[] = $ch & 0x01;
1983 private function qr_encode_kanji($data, $version_group) {
1984 $code = array(1, 0, 0, 0);
1985 $length = strlen($data);
1986 switch ($version_group) {
1988 $code[] = $length & 0x1000;
1989 $code[] = $length & 0x0800;
1991 $code[] = $length & 0x0400;
1992 $code[] = $length & 0x0200;
1994 $code[] = $length & 0x0100;
1995 $code[] = $length & 0x0080;
1996 $code[] = $length & 0x0040;
1997 $code[] = $length & 0x0020;
1998 $code[] = $length & 0x0010;
1999 $code[] = $length & 0x0008;
2000 $code[] = $length & 0x0004;
2001 $code[] = $length & 0x0002;
2003 for ($i = 0; $i < $length; $i += 2) {
2004 $group = substr($data, $i, 2);
2005 $c1 = ord(substr($group, 0, 1));
2006 $c2 = ord(substr($group, 1, 1));
2007 if ($c1 >= 0x81 && $c1 <= 0x9F && $c2 >= 0x40 && $c2 <= 0xFC) {
2008 $ch = ($c1 - 0x81) * 0xC0 + ($c2 - 0x40);
2010 ($c1 >= 0xE0 && $c1 <= 0xEA && $c2 >= 0x40 && $c2 <= 0xFC) ||
2011 ($c1 == 0xEB && $c2 >= 0x40 && $c2 <= 0xBF)
2013 $ch = ($c1 - 0xC1) * 0xC0 + ($c2 - 0x40);
2017 $code[] = $ch & 0x1000;
2018 $code[] = $ch & 0x0800;
2019 $code[] = $ch & 0x0400;
2020 $code[] = $ch & 0x0200;
2021 $code[] = $ch & 0x0100;
2022 $code[] = $ch & 0x0080;
2023 $code[] = $ch & 0x0040;
2024 $code[] = $ch & 0x0020;
2025 $code[] = $ch & 0x0010;
2026 $code[] = $ch & 0x0008;
2027 $code[] = $ch & 0x0004;
2028 $code[] = $ch & 0x0002;
2029 $code[] = $ch & 0x0001;
2034 private function qr_encode_ec($data, $ec_params, $version) {
2035 $blocks = $this->qr_ec_split($data, $ec_params);
2036 $ec_blocks = array();
2037 for ($i = 0, $n = count($blocks); $i < $n; $i++) {
2038 $ec_blocks[] = $this->qr_ec_divide($blocks[$i], $ec_params);
2040 $data = $this->qr_ec_interleave($blocks);
2041 $ec_data = $this->qr_ec_interleave($ec_blocks);
2043 foreach ($data as $ch) {
2044 $code[] = $ch & 0x80;
2045 $code[] = $ch & 0x40;
2046 $code[] = $ch & 0x20;
2047 $code[] = $ch & 0x10;
2048 $code[] = $ch & 0x08;
2049 $code[] = $ch & 0x04;
2050 $code[] = $ch & 0x02;
2051 $code[] = $ch & 0x01;
2053 foreach ($ec_data as $ch) {
2054 $code[] = $ch & 0x80;
2055 $code[] = $ch & 0x40;
2056 $code[] = $ch & 0x20;
2057 $code[] = $ch & 0x10;
2058 $code[] = $ch & 0x08;
2059 $code[] = $ch & 0x04;
2060 $code[] = $ch & 0x02;
2061 $code[] = $ch & 0x01;
2063 for ($n = $this->qr_remainder_bits[$version - 1]; $n > 0; $n--) {
2069 private function qr_ec_split($data, $ec_params) {
2072 for ($i = $ec_params[2], $length = $ec_params[3]; $i > 0; $i--) {
2073 $blocks[] = array_slice($data, $offset, $length);
2076 for ($i = $ec_params[4], $length = $ec_params[5]; $i > 0; $i--) {
2077 $blocks[] = array_slice($data, $offset, $length);
2083 private function qr_ec_divide($data, $ec_params) {
2084 $num_data = count($data);
2085 $num_error = $ec_params[1];
2086 $generator = $this->qr_ec_polynomials[$num_error];
2088 for ($i = 0; $i < $num_error; $i++) {
2091 for ($i = 0; $i < $num_data; $i++) {
2093 $leadterm = $this->qr_log[$message[$i]];
2094 for ($j = 0; $j <= $num_error; $j++) {
2095 $term = ($generator[$j] + $leadterm) % 255;
2096 $message[$i + $j] ^= $this->qr_exp[$term];
2100 return array_slice($message, $num_data, $num_error);
2103 private function qr_ec_interleave($blocks) {
2105 $num_blocks = count($blocks);
2106 for ($offset = 0;
true; $offset++) {
2108 for ($i = 0; $i < $num_blocks; $i++) {
2109 if (isset($blocks[$i][$offset])) {
2110 $data[] = $blocks[$i][$offset];
2119 private function qr_create_matrix($version, $data) {
2120 $size = $version * 4 + 17;
2122 for ($i = 0; $i < $size; $i++) {
2124 for ($j = 0; $j < $size; $j++) {
2130 for ($i = 0; $i < 8; $i++) {
2131 for ($j = 0; $j < 8; $j++) {
2132 $m = (($i == 7 || $j == 7) ? 2 :
2133 (($i == 0 || $j == 0 || $i == 6 || $j == 6) ? 3 :
2134 (($i == 1 || $j == 1 || $i == 5 || $j == 5) ? 2 : 3)));
2135 $matrix[$i][$j] = $m;
2136 $matrix[$size - $i - 1][$j] = $m;
2137 $matrix[$i][$size - $j - 1] = $m;
2141 if ($version >= 2) {
2142 $alignment = $this->qr_alignment_patterns[$version - 2];
2143 foreach ($alignment as $i) {
2144 foreach ($alignment as $j) {
2145 if (!$matrix[$i][$j]) {
2146 for ($ii = -2; $ii <= 2; $ii++) {
2147 for ($jj = -2; $jj <= 2; $jj++) {
2148 $m = (max(abs($ii), abs($jj)) & 1) ^ 3;
2149 $matrix[$i + $ii][$j + $jj] = $m;
2157 for ($i = $size - 9; $i >= 8; $i--) {
2158 $matrix[$i][6] = ($i & 1) ^ 3;
2159 $matrix[6][$i] = ($i & 1) ^ 3;
2162 $matrix[$size - 8][8] = 3;
2164 for ($i = 0; $i <= 8; $i++) {
2165 if (!$matrix[$i][8]) $matrix[$i][8] = 1;
2166 if (!$matrix[8][$i]) $matrix[8][$i] = 1;
2167 if ($i && !$matrix[$size - $i][8]) $matrix[$size - $i][8] = 1;
2168 if ($i && !$matrix[8][$size - $i]) $matrix[8][$size - $i] = 1;
2171 if ($version >= 7) {
2172 for ($i = 9; $i < 12; $i++) {
2173 for ($j = 0; $j < 6; $j++) {
2174 $matrix[$size - $i][$j] = 1;
2175 $matrix[$j][$size - $i] = 1;
2184 $length = count($data);
2185 while ($col > 0 && $offset < $length) {
2186 if (!$matrix[$row][$col]) {
2187 $matrix[$row][$col] = $data[$offset] ? 5 : 4;
2190 if (!$matrix[$row][$col - 1]) {
2191 $matrix[$row][$col - 1] = $data[$offset] ? 5 : 4;
2195 if ($row < 0 || $row >= $size) {
2199 if ($col == 6) $col--;
2202 return array($size, $matrix);
2205 private function qr_apply_best_mask($matrix, $size) {
2207 $best_matrix = $this->qr_apply_mask($matrix, $size, $best_mask);
2208 $best_penalty = $this->qr_penalty($best_matrix, $size);
2209 for ($test_mask = 1; $test_mask < 8; $test_mask++) {
2210 $test_matrix = $this->qr_apply_mask($matrix, $size, $test_mask);
2211 $test_penalty = $this->qr_penalty($test_matrix, $size);
2212 if ($test_penalty < $best_penalty) {
2213 $best_mask = $test_mask;
2214 $best_matrix = $test_matrix;
2215 $best_penalty = $test_penalty;
2218 return array($best_mask, $best_matrix);
2221 private function qr_apply_mask($matrix, $size, $mask) {
2222 for ($i = 0; $i < $size; $i++) {
2223 for ($j = 0; $j < $size; $j++) {
2224 if ($matrix[$i][$j] >= 4) {
2225 if ($this->qr_mask($mask, $i, $j)) {
2226 $matrix[$i][$j] ^= 1;
2234 private function qr_mask($mask, $r, $c) {
2236 case 0:
return !( ($r + $c) % 2 );
2237 case 1:
return !( ($r ) % 2 );
2238 case 2:
return !( ( $c) % 3 );
2239 case 3:
return !( ($r + $c) % 3 );
2240 case 4:
return !( (floor(($r) / 2) + floor(($c) / 3)) % 2 );
2241 case 5:
return !( ((($r * $c) % 2) + (($r * $c) % 3)) );
2242 case 6:
return !( ((($r * $c) % 2) + (($r * $c) % 3)) % 2 );
2243 case 7:
return !( ((($r + $c) % 2) + (($r * $c) % 3)) % 2 );
2247 private function qr_penalty(&$matrix, $size) {
2248 $score = $this->qr_penalty_1($matrix, $size);
2249 $score += $this->qr_penalty_2($matrix, $size);
2250 $score += $this->qr_penalty_3($matrix, $size);
2251 $score += $this->qr_penalty_4($matrix, $size);
2255 private function qr_penalty_1(&$matrix, $size) {
2257 for ($i = 0; $i < $size; $i++) {
2262 for ($j = 0; $j < $size; $j++) {
2263 $rv = ($matrix[$i][$j] == 5 || $matrix[$i][$j] == 3) ? 1 : 0;
2264 $cv = ($matrix[$j][$i] == 5 || $matrix[$j][$i] == 3) ? 1 : 0;
2265 if ($rv == $rowvalue) {
2268 if ($rowcount >= 5) $score += $rowcount - 2;
2272 if ($cv == $colvalue) {
2275 if ($colcount >= 5) $score += $colcount - 2;
2280 if ($rowcount >= 5) $score += $rowcount - 2;
2281 if ($colcount >= 5) $score += $colcount - 2;
2286 private function qr_penalty_2(&$matrix, $size) {
2288 for ($i = 1; $i < $size; $i++) {
2289 for ($j = 1; $j < $size; $j++) {
2290 $v1 = $matrix[$i - 1][$j - 1];
2291 $v2 = $matrix[$i - 1][$j ];
2292 $v3 = $matrix[$i ][$j - 1];
2293 $v4 = $matrix[$i ][$j ];
2294 $v1 = ($v1 == 5 || $v1 == 3) ? 1 : 0;
2295 $v2 = ($v2 == 5 || $v2 == 3) ? 1 : 0;
2296 $v3 = ($v3 == 5 || $v3 == 3) ? 1 : 0;
2297 $v4 = ($v4 == 5 || $v4 == 3) ? 1 : 0;
2298 if ($v1 == $v2 && $v2 == $v3 && $v3 == $v4) $score += 3;
2304 private function qr_penalty_3(&$matrix, $size) {
2306 for ($i = 0; $i < $size; $i++) {
2309 for ($j = 0; $j < 11; $j++) {
2310 $rv = ($matrix[$i][$j] == 5 || $matrix[$i][$j] == 3) ? 1 : 0;
2311 $cv = ($matrix[$j][$i] == 5 || $matrix[$j][$i] == 3) ? 1 : 0;
2312 $rowvalue = (($rowvalue << 1) & 0x7FF) | $rv;
2313 $colvalue = (($colvalue << 1) & 0x7FF) | $cv;
2315 if ($rowvalue == 0x5D0 || $rowvalue == 0x5D) $score += 40;
2316 if ($colvalue == 0x5D0 || $colvalue == 0x5D) $score += 40;
2317 for ($j = 11; $j < $size; $j++) {
2318 $rv = ($matrix[$i][$j] == 5 || $matrix[$i][$j] == 3) ? 1 : 0;
2319 $cv = ($matrix[$j][$i] == 5 || $matrix[$j][$i] == 3) ? 1 : 0;
2320 $rowvalue = (($rowvalue << 1) & 0x7FF) | $rv;
2321 $colvalue = (($colvalue << 1) & 0x7FF) | $cv;
2322 if ($rowvalue == 0x5D0 || $rowvalue == 0x5D) $score += 40;
2323 if ($colvalue == 0x5D0 || $colvalue == 0x5D) $score += 40;
2329 private function qr_penalty_4(&$matrix, $size) {
2331 for ($i = 0; $i < $size; $i++) {
2332 for ($j = 0; $j < $size; $j++) {
2333 if ($matrix[$i][$j] == 5 || $matrix[$i][$j] == 3) {
2339 $dark /= $size * $size;
2340 $a = abs(floor($dark) - 10);
2341 $b = abs(ceil($dark) - 10);
2342 return min($a, $b) * 10;
2345 private function qr_finalize_matrix(
2346 $matrix, $size, $ecl, $mask, $version
2349 $format = $this->qr_format_info[$ecl * 8 + $mask];
2350 $matrix[8][0] = $format[0];
2351 $matrix[8][1] = $format[1];
2352 $matrix[8][2] = $format[2];
2353 $matrix[8][3] = $format[3];
2354 $matrix[8][4] = $format[4];
2355 $matrix[8][5] = $format[5];
2356 $matrix[8][7] = $format[6];
2357 $matrix[8][8] = $format[7];
2358 $matrix[7][8] = $format[8];
2359 $matrix[5][8] = $format[9];
2360 $matrix[4][8] = $format[10];
2361 $matrix[3][8] = $format[11];
2362 $matrix[2][8] = $format[12];
2363 $matrix[1][8] = $format[13];
2364 $matrix[0][8] = $format[14];
2365 $matrix[$size - 1][8] = $format[0];
2366 $matrix[$size - 2][8] = $format[1];
2367 $matrix[$size - 3][8] = $format[2];
2368 $matrix[$size - 4][8] = $format[3];
2369 $matrix[$size - 5][8] = $format[4];
2370 $matrix[$size - 6][8] = $format[5];
2371 $matrix[$size - 7][8] = $format[6];
2372 $matrix[8][$size - 8] = $format[7];
2373 $matrix[8][$size - 7] = $format[8];
2374 $matrix[8][$size - 6] = $format[9];
2375 $matrix[8][$size - 5] = $format[10];
2376 $matrix[8][$size - 4] = $format[11];
2377 $matrix[8][$size - 3] = $format[12];
2378 $matrix[8][$size - 2] = $format[13];
2379 $matrix[8][$size - 1] = $format[14];
2381 if ($version >= 7) {
2382 $version = $this->qr_version_info[$version - 7];
2383 for ($i = 0; $i < 18; $i++) {
2384 $r = $size - 9 - ($i % 3);
2385 $c = 5 - floor($i / 3);
2386 $matrix[$r][$c] = $version[$i];
2387 $matrix[$c][$r] = $version[$i];
2391 for ($i = 0; $i < $size; $i++) {
2392 for ($j = 0; $j < $size; $j++) {
2393 $matrix[$i][$j] &= 1;
2402 private $qr_capacity = array(
2403 array(array( 41, 25, 17, 10), array( 34, 20, 14, 8),
2404 array( 27, 16, 11, 7), array( 17, 10, 7, 4)),
2405 array(array( 77, 47, 32, 20), array( 63, 38, 26, 16),
2406 array( 48, 29, 20, 12), array( 34, 20, 14, 8)),
2407 array(array( 127, 77, 53, 32), array( 101, 61, 42, 26),
2408 array( 77, 47, 32, 20), array( 58, 35, 24, 15)),
2409 array(array( 187, 114, 78, 48), array( 149, 90, 62, 38),
2410 array( 111, 67, 46, 28), array( 82, 50, 34, 21)),
2411 array(array( 255, 154, 106, 65), array( 202, 122, 84, 52),
2412 array( 144, 87, 60, 37), array( 106, 64, 44, 27)),
2413 array(array( 322, 195, 134, 82), array( 255, 154, 106, 65),
2414 array( 178, 108, 74, 45), array( 139, 84, 58, 36)),
2415 array(array( 370, 224, 154, 95), array( 293, 178, 122, 75),
2416 array( 207, 125, 86, 53), array( 154, 93, 64, 39)),
2417 array(array( 461, 279, 192, 118), array( 365, 221, 152, 93),
2418 array( 259, 157, 108, 66), array( 202, 122, 84, 52)),
2419 array(array( 552, 335, 230, 141), array( 432, 262, 180, 111),
2420 array( 312, 189, 130, 80), array( 235, 143, 98, 60)),
2421 array(array( 652, 395, 271, 167), array( 513, 311, 213, 131),
2422 array( 364, 221, 151, 93), array( 288, 174, 119, 74)),
2423 array(array( 772, 468, 321, 198), array( 604, 366, 251, 155),
2424 array( 427, 259, 177, 109), array( 331, 200, 137, 85)),
2425 array(array( 883, 535, 367, 226), array( 691, 419, 287, 177),
2426 array( 489, 296, 203, 125), array( 374, 227, 155, 96)),
2427 array(array(1022, 619, 425, 262), array( 796, 483, 331, 204),
2428 array( 580, 352, 241, 149), array( 427, 259, 177, 109)),
2429 array(array(1101, 667, 458, 282), array( 871, 528, 362, 223),
2430 array( 621, 376, 258, 159), array( 468, 283, 194, 120)),
2431 array(array(1250, 758, 520, 320), array( 991, 600, 412, 254),
2432 array( 703, 426, 292, 180), array( 530, 321, 220, 136)),
2433 array(array(1408, 854, 586, 361), array(1082, 656, 450, 277),
2434 array( 775, 470, 322, 198), array( 602, 365, 250, 154)),
2435 array(array(1548, 938, 644, 397), array(1212, 734, 504, 310),
2436 array( 876, 531, 364, 224), array( 674, 408, 280, 173)),
2437 array(array(1725, 1046, 718, 442), array(1346, 816, 560, 345),
2438 array( 948, 574, 394, 243), array( 746, 452, 310, 191)),
2439 array(array(1903, 1153, 792, 488), array(1500, 909, 624, 384),
2440 array(1063, 644, 442, 272), array( 813, 493, 338, 208)),
2441 array(array(2061, 1249, 858, 528), array(1600, 970, 666, 410),
2442 array(1159, 702, 482, 297), array( 919, 557, 382, 235)),
2443 array(array(2232, 1352, 929, 572), array(1708, 1035, 711, 438),
2444 array(1224, 742, 509, 314), array( 969, 587, 403, 248)),
2445 array(array(2409, 1460, 1003, 618), array(1872, 1134, 779, 480),
2446 array(1358, 823, 565, 348), array(1056, 640, 439, 270)),
2447 array(array(2620, 1588, 1091, 672), array(2059, 1248, 857, 528),
2448 array(1468, 890, 611, 376), array(1108, 672, 461, 284)),
2449 array(array(2812, 1704, 1171, 721), array(2188, 1326, 911, 561),
2450 array(1588, 963, 661, 407), array(1228, 744, 511, 315)),
2451 array(array(3057, 1853, 1273, 784), array(2395, 1451, 997, 614),
2452 array(1718, 1041, 715, 440), array(1286, 779, 535, 330)),
2453 array(array(3283, 1990, 1367, 842), array(2544, 1542, 1059, 652),
2454 array(1804, 1094, 751, 462), array(1425, 864, 593, 365)),
2455 array(array(3517, 2132, 1465, 902), array(2701, 1637, 1125, 692),
2456 array(1933, 1172, 805, 496), array(1501, 910, 625, 385)),
2457 array(array(3669, 2223, 1528, 940), array(2857, 1732, 1190, 732),
2458 array(2085, 1263, 868, 534), array(1581, 958, 658, 405)),
2459 array(array(3909, 2369, 1628, 1002), array(3035, 1839, 1264, 778),
2460 array(2181, 1322, 908, 559), array(1677, 1016, 698, 430)),
2461 array(array(4158, 2520, 1732, 1066), array(3289, 1994, 1370, 843),
2462 array(2358, 1429, 982, 604), array(1782, 1080, 742, 457)),
2463 array(array(4417, 2677, 1840, 1132), array(3486, 2113, 1452, 894),
2464 array(2473, 1499, 1030, 634), array(1897, 1150, 790, 486)),
2465 array(array(4686, 2840, 1952, 1201), array(3693, 2238, 1538, 947),
2466 array(2670, 1618, 1112, 684), array(2022, 1226, 842, 518)),
2467 array(array(4965, 3009, 2068, 1273), array(3909, 2369, 1628, 1002),
2468 array(2805, 1700, 1168, 719), array(2157, 1307, 898, 553)),
2469 array(array(5253, 3183, 2188, 1347), array(4134, 2506, 1722, 1060),
2470 array(2949, 1787, 1228, 756), array(2301, 1394, 958, 590)),
2471 array(array(5529, 3351, 2303, 1417), array(4343, 2632, 1809, 1113),
2472 array(3081, 1867, 1283, 790), array(2361, 1431, 983, 605)),
2473 array(array(5836, 3537, 2431, 1496), array(4588, 2780, 1911, 1176),
2474 array(3244, 1966, 1351, 832), array(2524, 1530, 1051, 647)),
2475 array(array(6153, 3729, 2563, 1577), array(4775, 2894, 1989, 1224),
2476 array(3417, 2071, 1423, 876), array(2625, 1591, 1093, 673)),
2477 array(array(6479, 3927, 2699, 1661), array(5039, 3054, 2099, 1292),
2478 array(3599, 2181, 1499, 923), array(2735, 1658, 1139, 701)),
2479 array(array(6743, 4087, 2809, 1729), array(5313, 3220, 2213, 1362),
2480 array(3791, 2298, 1579, 972), array(2927, 1774, 1219, 750)),
2481 array(array(7089, 4296, 2953, 1817), array(5596, 3391, 2331, 1435),
2482 array(3993, 2420, 1663, 1024), array(3057, 1852, 1273, 784)),
2495 private $qr_ec_params = array(
2496 array( 19, 7, 1, 19, 0, 0 ),
2497 array( 16, 10, 1, 16, 0, 0 ),
2498 array( 13, 13, 1, 13, 0, 0 ),
2499 array( 9, 17, 1, 9, 0, 0 ),
2500 array( 34, 10, 1, 34, 0, 0 ),
2501 array( 28, 16, 1, 28, 0, 0 ),
2502 array( 22, 22, 1, 22, 0, 0 ),
2503 array( 16, 28, 1, 16, 0, 0 ),
2504 array( 55, 15, 1, 55, 0, 0 ),
2505 array( 44, 26, 1, 44, 0, 0 ),
2506 array( 34, 18, 2, 17, 0, 0 ),
2507 array( 26, 22, 2, 13, 0, 0 ),
2508 array( 80, 20, 1, 80, 0, 0 ),
2509 array( 64, 18, 2, 32, 0, 0 ),
2510 array( 48, 26, 2, 24, 0, 0 ),
2511 array( 36, 16, 4, 9, 0, 0 ),
2512 array( 108, 26, 1, 108, 0, 0 ),
2513 array( 86, 24, 2, 43, 0, 0 ),
2514 array( 62, 18, 2, 15, 2, 16 ),
2515 array( 46, 22, 2, 11, 2, 12 ),
2516 array( 136, 18, 2, 68, 0, 0 ),
2517 array( 108, 16, 4, 27, 0, 0 ),
2518 array( 76, 24, 4, 19, 0, 0 ),
2519 array( 60, 28, 4, 15, 0, 0 ),
2520 array( 156, 20, 2, 78, 0, 0 ),
2521 array( 124, 18, 4, 31, 0, 0 ),
2522 array( 88, 18, 2, 14, 4, 15 ),
2523 array( 66, 26, 4, 13, 1, 14 ),
2524 array( 194, 24, 2, 97, 0, 0 ),
2525 array( 154, 22, 2, 38, 2, 39 ),
2526 array( 110, 22, 4, 18, 2, 19 ),
2527 array( 86, 26, 4, 14, 2, 15 ),
2528 array( 232, 30, 2, 116, 0, 0 ),
2529 array( 182, 22, 3, 36, 2, 37 ),
2530 array( 132, 20, 4, 16, 4, 17 ),
2531 array( 100, 24, 4, 12, 4, 13 ),
2532 array( 274, 18, 2, 68, 2, 69 ),
2533 array( 216, 26, 4, 43, 1, 44 ),
2534 array( 154, 24, 6, 19, 2, 20 ),
2535 array( 122, 28, 6, 15, 2, 16 ),
2536 array( 324, 20, 4, 81, 0, 0 ),
2537 array( 254, 30, 1, 50, 4, 51 ),
2538 array( 180, 28, 4, 22, 4, 23 ),
2539 array( 140, 24, 3, 12, 8, 13 ),
2540 array( 370, 24, 2, 92, 2, 93 ),
2541 array( 290, 22, 6, 36, 2, 37 ),
2542 array( 206, 26, 4, 20, 6, 21 ),
2543 array( 158, 28, 7, 14, 4, 15 ),
2544 array( 428, 26, 4, 107, 0, 0 ),
2545 array( 334, 22, 8, 37, 1, 38 ),
2546 array( 244, 24, 8, 20, 4, 21 ),
2547 array( 180, 22, 12, 11, 4, 12 ),
2548 array( 461, 30, 3, 115, 1, 116 ),
2549 array( 365, 24, 4, 40, 5, 41 ),
2550 array( 261, 20, 11, 16, 5, 17 ),
2551 array( 197, 24, 11, 12, 5, 13 ),
2552 array( 523, 22, 5, 87, 1, 88 ),
2553 array( 415, 24, 5, 41, 5, 42 ),
2554 array( 295, 30, 5, 24, 7, 25 ),
2555 array( 223, 24, 11, 12, 7, 13 ),
2556 array( 589, 24, 5, 98, 1, 99 ),
2557 array( 453, 28, 7, 45, 3, 46 ),
2558 array( 325, 24, 15, 19, 2, 20 ),
2559 array( 253, 30, 3, 15, 13, 16 ),
2560 array( 647, 28, 1, 107, 5, 108 ),
2561 array( 507, 28, 10, 46, 1, 47 ),
2562 array( 367, 28, 1, 22, 15, 23 ),
2563 array( 283, 28, 2, 14, 17, 15 ),
2564 array( 721, 30, 5, 120, 1, 121 ),
2565 array( 563, 26, 9, 43, 4, 44 ),
2566 array( 397, 28, 17, 22, 1, 23 ),
2567 array( 313, 28, 2, 14, 19, 15 ),
2568 array( 795, 28, 3, 113, 4, 114 ),
2569 array( 627, 26, 3, 44, 11, 45 ),
2570 array( 445, 26, 17, 21, 4, 22 ),
2571 array( 341, 26, 9, 13, 16, 14 ),
2572 array( 861, 28, 3, 107, 5, 108 ),
2573 array( 669, 26, 3, 41, 13, 42 ),
2574 array( 485, 30, 15, 24, 5, 25 ),
2575 array( 385, 28, 15, 15, 10, 16 ),
2576 array( 932, 28, 4, 116, 4, 117 ),
2577 array( 714, 26, 17, 42, 0, 0 ),
2578 array( 512, 28, 17, 22, 6, 23 ),
2579 array( 406, 30, 19, 16, 6, 17 ),
2580 array( 1006, 28, 2, 111, 7, 112 ),
2581 array( 782, 28, 17, 46, 0, 0 ),
2582 array( 568, 30, 7, 24, 16, 25 ),
2583 array( 442, 24, 34, 13, 0, 0 ),
2584 array( 1094, 30, 4, 121, 5, 122 ),
2585 array( 860, 28, 4, 47, 14, 48 ),
2586 array( 614, 30, 11, 24, 14, 25 ),
2587 array( 464, 30, 16, 15, 14, 16 ),
2588 array( 1174, 30, 6, 117, 4, 118 ),
2589 array( 914, 28, 6, 45, 14, 46 ),
2590 array( 664, 30, 11, 24, 16, 25 ),
2591 array( 514, 30, 30, 16, 2, 17 ),
2592 array( 1276, 26, 8, 106, 4, 107 ),
2593 array( 1000, 28, 8, 47, 13, 48 ),
2594 array( 718, 30, 7, 24, 22, 25 ),
2595 array( 538, 30, 22, 15, 13, 16 ),
2596 array( 1370, 28, 10, 114, 2, 115 ),
2597 array( 1062, 28, 19, 46, 4, 47 ),
2598 array( 754, 28, 28, 22, 6, 23 ),
2599 array( 596, 30, 33, 16, 4, 17 ),
2600 array( 1468, 30, 8, 122, 4, 123 ),
2601 array( 1128, 28, 22, 45, 3, 46 ),
2602 array( 808, 30, 8, 23, 26, 24 ),
2603 array( 628, 30, 12, 15, 28, 16 ),
2604 array( 1531, 30, 3, 117, 10, 118 ),
2605 array( 1193, 28, 3, 45, 23, 46 ),
2606 array( 871, 30, 4, 24, 31, 25 ),
2607 array( 661, 30, 11, 15, 31, 16 ),
2608 array( 1631, 30, 7, 116, 7, 117 ),
2609 array( 1267, 28, 21, 45, 7, 46 ),
2610 array( 911, 30, 1, 23, 37, 24 ),
2611 array( 701, 30, 19, 15, 26, 16 ),
2612 array( 1735, 30, 5, 115, 10, 116 ),
2613 array( 1373, 28, 19, 47, 10, 48 ),
2614 array( 985, 30, 15, 24, 25, 25 ),
2615 array( 745, 30, 23, 15, 25, 16 ),
2616 array( 1843, 30, 13, 115, 3, 116 ),
2617 array( 1455, 28, 2, 46, 29, 47 ),
2618 array( 1033, 30, 42, 24, 1, 25 ),
2619 array( 793, 30, 23, 15, 28, 16 ),
2620 array( 1955, 30, 17, 115, 0, 0 ),
2621 array( 1541, 28, 10, 46, 23, 47 ),
2622 array( 1115, 30, 10, 24, 35, 25 ),
2623 array( 845, 30, 19, 15, 35, 16 ),
2624 array( 2071, 30, 17, 115, 1, 116 ),
2625 array( 1631, 28, 14, 46, 21, 47 ),
2626 array( 1171, 30, 29, 24, 19, 25 ),
2627 array( 901, 30, 11, 15, 46, 16 ),
2628 array( 2191, 30, 13, 115, 6, 116 ),
2629 array( 1725, 28, 14, 46, 23, 47 ),
2630 array( 1231, 30, 44, 24, 7, 25 ),
2631 array( 961, 30, 59, 16, 1, 17 ),
2632 array( 2306, 30, 12, 121, 7, 122 ),
2633 array( 1812, 28, 12, 47, 26, 48 ),
2634 array( 1286, 30, 39, 24, 14, 25 ),
2635 array( 986, 30, 22, 15, 41, 16 ),
2636 array( 2434, 30, 6, 121, 14, 122 ),
2637 array( 1914, 28, 6, 47, 34, 48 ),
2638 array( 1354, 30, 46, 24, 10, 25 ),
2639 array( 1054, 30, 2, 15, 64, 16 ),
2640 array( 2566, 30, 17, 122, 4, 123 ),
2641 array( 1992, 28, 29, 46, 14, 47 ),
2642 array( 1426, 30, 49, 24, 10, 25 ),
2643 array( 1096, 30, 24, 15, 46, 16 ),
2644 array( 2702, 30, 4, 122, 18, 123 ),
2645 array( 2102, 28, 13, 46, 32, 47 ),
2646 array( 1502, 30, 48, 24, 14, 25 ),
2647 array( 1142, 30, 42, 15, 32, 16 ),
2648 array( 2812, 30, 20, 117, 4, 118 ),
2649 array( 2216, 28, 40, 47, 7, 48 ),
2650 array( 1582, 30, 43, 24, 22, 25 ),
2651 array( 1222, 30, 10, 15, 67, 16 ),
2652 array( 2956, 30, 19, 118, 6, 119 ),
2653 array( 2334, 28, 18, 47, 31, 48 ),
2654 array( 1666, 30, 34, 24, 34, 25 ),
2655 array( 1276, 30, 20, 15, 61, 16 ),
2658 private $qr_ec_polynomials = array(
2660 0, 87, 229, 146, 149, 238, 102, 21
2663 0, 251, 67, 46, 61, 118, 70, 64, 94, 32, 45
2666 0, 74, 152, 176, 100, 86, 100,
2667 106, 104, 130, 218, 206, 140, 78
2670 0, 8, 183, 61, 91, 202, 37, 51,
2671 58, 58, 237, 140, 124, 5, 99, 105
2674 0, 120, 104, 107, 109, 102, 161, 76, 3,
2675 91, 191, 147, 169, 182, 194, 225, 120
2678 0, 43, 139, 206, 78, 43, 239, 123, 206,
2679 214, 147, 24, 99, 150, 39, 243, 163, 136
2682 0, 215, 234, 158, 94, 184, 97, 118, 170, 79,
2683 187, 152, 148, 252, 179, 5, 98, 96, 153
2686 0, 17, 60, 79, 50, 61, 163, 26, 187, 202, 180,
2687 221, 225, 83, 239, 156, 164, 212, 212, 188, 190
2690 0, 210, 171, 247, 242, 93, 230, 14, 109, 221, 53, 200,
2691 74, 8, 172, 98, 80, 219, 134, 160, 105, 165, 231
2694 0, 229, 121, 135, 48, 211, 117, 251, 126, 159, 180, 169,
2695 152, 192, 226, 228, 218, 111, 0, 117, 232, 87, 96, 227, 21
2698 0, 173, 125, 158, 2, 103, 182, 118, 17,
2699 145, 201, 111, 28, 165, 53, 161, 21, 245,
2700 142, 13, 102, 48, 227, 153, 145, 218, 70
2703 0, 168, 223, 200, 104, 224, 234, 108, 180,
2704 110, 190, 195, 147, 205, 27, 232, 201, 21, 43,
2705 245, 87, 42, 195, 212, 119, 242, 37, 9, 123
2708 0, 41, 173, 145, 152, 216, 31, 179, 182, 50, 48,
2709 110, 86, 239, 96, 222, 125, 42, 173, 226, 193,
2710 224, 130, 156, 37, 251, 216, 238, 40, 192, 180
2714 private $qr_log = array(
2715 0, 0, 1, 25, 2, 50, 26, 198,
2716 3, 223, 51, 238, 27, 104, 199, 75,
2717 4, 100, 224, 14, 52, 141, 239, 129,
2718 28, 193, 105, 248, 200, 8, 76, 113,
2719 5, 138, 101, 47, 225, 36, 15, 33,
2720 53, 147, 142, 218, 240, 18, 130, 69,
2721 29, 181, 194, 125, 106, 39, 249, 185,
2722 201, 154, 9, 120, 77, 228, 114, 166,
2723 6, 191, 139, 98, 102, 221, 48, 253,
2724 226, 152, 37, 179, 16, 145, 34, 136,
2725 54, 208, 148, 206, 143, 150, 219, 189,
2726 241, 210, 19, 92, 131, 56, 70, 64,
2727 30, 66, 182, 163, 195, 72, 126, 110,
2728 107, 58, 40, 84, 250, 133, 186, 61,
2729 202, 94, 155, 159, 10, 21, 121, 43,
2730 78, 212, 229, 172, 115, 243, 167, 87,
2731 7, 112, 192, 247, 140, 128, 99, 13,
2732 103, 74, 222, 237, 49, 197, 254, 24,
2733 227, 165, 153, 119, 38, 184, 180, 124,
2734 17, 68, 146, 217, 35, 32, 137, 46,
2735 55, 63, 209, 91, 149, 188, 207, 205,
2736 144, 135, 151, 178, 220, 252, 190, 97,
2737 242, 86, 211, 171, 20, 42, 93, 158,
2738 132, 60, 57, 83, 71, 109, 65, 162,
2739 31, 45, 67, 216, 183, 123, 164, 118,
2740 196, 23, 73, 236, 127, 12, 111, 246,
2741 108, 161, 59, 82, 41, 157, 85, 170,
2742 251, 96, 134, 177, 187, 204, 62, 90,
2743 203, 89, 95, 176, 156, 169, 160, 81,
2744 11, 245, 22, 235, 122, 117, 44, 215,
2745 79, 174, 213, 233, 230, 231, 173, 232,
2746 116, 214, 244, 234, 168, 80, 88, 175,
2749 private $qr_exp = array(
2750 1, 2, 4, 8, 16, 32, 64, 128,
2751 29, 58, 116, 232, 205, 135, 19, 38,
2752 76, 152, 45, 90, 180, 117, 234, 201,
2753 143, 3, 6, 12, 24, 48, 96, 192,
2754 157, 39, 78, 156, 37, 74, 148, 53,
2755 106, 212, 181, 119, 238, 193, 159, 35,
2756 70, 140, 5, 10, 20, 40, 80, 160,
2757 93, 186, 105, 210, 185, 111, 222, 161,
2758 95, 190, 97, 194, 153, 47, 94, 188,
2759 101, 202, 137, 15, 30, 60, 120, 240,
2760 253, 231, 211, 187, 107, 214, 177, 127,
2761 254, 225, 223, 163, 91, 182, 113, 226,
2762 217, 175, 67, 134, 17, 34, 68, 136,
2763 13, 26, 52, 104, 208, 189, 103, 206,
2764 129, 31, 62, 124, 248, 237, 199, 147,
2765 59, 118, 236, 197, 151, 51, 102, 204,
2766 133, 23, 46, 92, 184, 109, 218, 169,
2767 79, 158, 33, 66, 132, 21, 42, 84,
2768 168, 77, 154, 41, 82, 164, 85, 170,
2769 73, 146, 57, 114, 228, 213, 183, 115,
2770 230, 209, 191, 99, 198, 145, 63, 126,
2771 252, 229, 215, 179, 123, 246, 241, 255,
2772 227, 219, 171, 75, 150, 49, 98, 196,
2773 149, 55, 110, 220, 165, 87, 174, 65,
2774 130, 25, 50, 100, 200, 141, 7, 14,
2775 28, 56, 112, 224, 221, 167, 83, 166,
2776 81, 162, 89, 178, 121, 242, 249, 239,
2777 195, 155, 43, 86, 172, 69, 138, 9,
2778 18, 36, 72, 144, 61, 122, 244, 245,
2779 247, 243, 251, 235, 203, 139, 11, 22,
2780 44, 88, 176, 125, 250, 233, 207, 131,
2781 27, 54, 108, 216, 173, 71, 142, 1,
2784 private $qr_remainder_bits = array(
2785 0, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 3,
2786 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0,
2789 private $qr_alignment_patterns = array(
2802 array(6, 26, 46, 66),
2803 array(6, 26, 48, 70),
2804 array(6, 26, 50, 74),
2805 array(6, 30, 54, 78),
2806 array(6, 30, 56, 82),
2807 array(6, 30, 58, 86),
2808 array(6, 34, 62, 90),
2809 array(6, 28, 50, 72, 94),
2810 array(6, 26, 50, 74, 98),
2811 array(6, 30, 54, 78, 102),
2812 array(6, 28, 54, 80, 106),
2813 array(6, 32, 58, 84, 110),
2814 array(6, 30, 58, 86, 114),
2815 array(6, 34, 62, 90, 118),
2816 array(6, 26, 50, 74, 98, 122),
2817 array(6, 30, 54, 78, 102, 126),
2818 array(6, 26, 52, 78, 104, 130),
2819 array(6, 30, 56, 82, 108, 134),
2820 array(6, 34, 60, 86, 112, 138),
2821 array(6, 30, 58, 86, 114, 142),
2822 array(6, 34, 62, 90, 118, 146),
2823 array(6, 30, 54, 78, 102, 126, 150),
2824 array(6, 24, 50, 76, 102, 128, 154),
2825 array(6, 28, 54, 80, 106, 132, 158),
2826 array(6, 32, 58, 84, 110, 136, 162),
2827 array(6, 26, 54, 82, 110, 138, 166),
2828 array(6, 30, 58, 86, 114, 142, 170),
2834 private $qr_format_info = array(
2835 array( 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0 ),
2836 array( 1, 1, 1, 0, 0, 1, 0, 1, 1, 1, 1, 0, 0, 1, 1 ),
2837 array( 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0 ),
2838 array( 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 1 ),
2839 array( 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 1 ),
2840 array( 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0 ),
2841 array( 1, 1, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1 ),
2842 array( 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 0 ),
2843 array( 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0 ),
2844 array( 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1 ),
2845 array( 1, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0 ),
2846 array( 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1 ),
2847 array( 1, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1 ),
2848 array( 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0 ),
2849 array( 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 0, 1, 1, 1 ),
2850 array( 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0 ),
2851 array( 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1 ),
2852 array( 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0 ),
2853 array( 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1 ),
2854 array( 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0 ),
2855 array( 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0 ),
2856 array( 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1 ),
2857 array( 0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0 ),
2858 array( 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1 ),
2859 array( 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1 ),
2860 array( 0, 0, 1, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0 ),
2861 array( 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1 ),
2862 array( 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0 ),
2863 array( 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 1, 0 ),
2864 array( 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1 ),
2865 array( 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0 ),
2866 array( 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1 ),
2870 private $qr_version_info = array(
2871 array( 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0 ),
2872 array( 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0 ),
2873 array( 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1 ),
2874 array( 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1 ),
2875 array( 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0 ),
2876 array( 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 1, 0 ),
2877 array( 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1 ),
2878 array( 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 1 ),
2879 array( 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0 ),
2880 array( 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0 ),
2881 array( 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 1 ),
2882 array( 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 1 ),
2883 array( 0, 1, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0 ),
2884 array( 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0 ),
2885 array( 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 1, 1 ),
2886 array( 0, 1, 0, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1 ),
2887 array( 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0 ),
2888 array( 0, 1, 1, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 1, 0, 0 ),
2889 array( 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1 ),
2890 array( 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1 ),
2891 array( 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0 ),
2892 array( 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0 ),
2893 array( 0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1 ),
2894 array( 0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1 ),
2895 array( 0, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0 ),
2896 array( 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1 ),
2897 array( 1, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0 ),
2898 array( 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 1, 0 ),
2899 array( 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1 ),
2900 array( 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0, 1, 1 ),
2901 array( 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 1, 0 ),
2902 array( 1, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0 ),
2903 array( 1, 0, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1 ),
2904 array( 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1 ),
2909 private function dmtx_encode($data, $rect, $fnc1) {
2910 list($data, $ec) = $this->dmtx_encode_data($data, $rect, $fnc1);
2911 $data = $this->dmtx_encode_ec($data, $ec);
2912 list($h, $w, $mtx) = $this->dmtx_create_matrix($ec, $data);
2915 'q' => array(1, 1, 1, 1),
2916 's' => array($w, $h),
2921 private function dmtx_encode_data($data, $rect, $fnc1) {
2923 $edata = ($fnc1 ? array(232) : array());
2924 $length = strlen($data);
2926 while ($offset < $length) {
2927 $ch1 = ord(substr($data, $offset, 1));
2929 if ($ch1 >= 0x30 && $ch1 <= 0x39) {
2930 $ch2 = ord(substr($data, $offset, 1));
2931 if ($ch2 >= 0x30 && $ch2 <= 0x39) {
2933 $edata[] = (($ch1 - 0x30) * 10) + ($ch2 - 0x30) + 130;
2935 $edata[] = $ch1 + 1;
2937 }
else if ($ch1 < 0x80) {
2938 $edata[] = $ch1 + 1;
2941 $edata[] = ($ch1 - 0x80) + 1;
2945 $length = count($edata);
2946 $ec_params = $this->dmtx_detect_version($length, $rect);
2947 if ($length > $ec_params[0]) {
2948 $length = $ec_params[0];
2949 $edata = array_slice($edata, 0, $length);
2950 if ($edata[$length - 1] == 235) {
2951 $edata[$length - 1] = 129;
2953 }
else if ($length < $ec_params[0]) {
2956 while ($length < $ec_params[0]) {
2958 $r = (($length * 149) % 253) + 1;
2959 $edata[] = ($r + 129) % 254;
2963 return array($edata, $ec_params);
2966 private function dmtx_detect_version($length, $rect) {
2967 for ($i = ($rect ? 24 : 0), $j = ($rect ? 30 : 24); $i < $j; $i++) {
2968 if ($length <= $this->dmtx_ec_params[$i][0]) {
2969 return $this->dmtx_ec_params[$i];
2972 return $this->dmtx_ec_params[$j - 1];
2975 private function dmtx_encode_ec($data, $ec_params) {
2976 $blocks = $this->dmtx_ec_split($data, $ec_params);
2977 for ($i = 0, $n = count($blocks); $i < $n; $i++) {
2978 $ec_block = $this->dmtx_ec_divide($blocks[$i], $ec_params);
2979 $blocks[$i] = array_merge($blocks[$i], $ec_block);
2981 return $this->dmtx_ec_interleave($blocks);
2984 private function dmtx_ec_split($data, $ec_params) {
2986 $num_blocks = $ec_params[2] + $ec_params[4];
2987 for ($i = 0; $i < $num_blocks; $i++) {
2988 $blocks[$i] = array();
2990 for ($i = 0, $length = count($data); $i < $length; $i++) {
2991 $blocks[$i % $num_blocks][] = $data[$i];
2996 private function dmtx_ec_divide($data, $ec_params) {
2997 $num_data = count($data);
2998 $num_error = $ec_params[1];
2999 $generator = $this->dmtx_ec_polynomials[$num_error];
3001 for ($i = 0; $i < $num_error; $i++) {
3004 for ($i = 0; $i < $num_data; $i++) {
3006 $leadterm = $this->dmtx_log[$message[$i]];
3007 for ($j = 0; $j <= $num_error; $j++) {
3008 $term = ($generator[$j] + $leadterm) % 255;
3009 $message[$i + $j] ^= $this->dmtx_exp[$term];
3013 return array_slice($message, $num_data, $num_error);
3016 private function dmtx_ec_interleave($blocks) {
3018 $num_blocks = count($blocks);
3019 for ($offset = 0;
true; $offset++) {
3021 for ($i = 0; $i < $num_blocks; $i++) {
3022 if (isset($blocks[$i][$offset])) {
3023 $data[] = $blocks[$i][$offset];
3032 private function dmtx_create_matrix($ec_params, $data) {
3034 $rheight = $ec_params[8] + 2;
3035 $rwidth = $ec_params[9] + 2;
3036 $height = $ec_params[6] * $rheight;
3037 $width = $ec_params[7] * $rwidth;
3039 for ($y = 0; $y < $height; $y++) {
3041 for ($x = 0; $x < $width; $x++) {
3043 ((($x + $y) % 2) == 0) ||
3044 (($x % $rwidth) == 0) ||
3045 (($y % $rheight) == ($rheight - 1))
3051 $rows = $ec_params[6] * $ec_params[8];
3052 $cols = $ec_params[7] * $ec_params[9];
3054 for ($y = 0; $y < $rows; $y++) {
3056 for ($x = 0; $x < $width; $x++) {
3061 $this->dmtx_place_data($matrix, $rows, $cols, $data);
3063 for ($yy = 0; $yy < $ec_params[6]; $yy++) {
3064 for ($xx = 0; $xx < $ec_params[7]; $xx++) {
3065 for ($y = 0; $y < $ec_params[8]; $y++) {
3066 for ($x = 0; $x < $ec_params[9]; $x++) {
3067 $row = $yy * $ec_params[8] + $y;
3068 $col = $xx * $ec_params[9] + $x;
3069 $b = $matrix[$row][$col];
3070 if (is_null($b))
continue;
3071 $row = $yy * $rheight + $y + 1;
3072 $col = $xx * $rwidth + $x + 1;
3073 $bitmap[$row][$col] = $b;
3079 return array($height, $width, $bitmap);
3082 private function dmtx_place_data(&$mtx, $rows, $cols, $data) {
3086 $length = count($data);
3087 while (($row < $rows || $col < $cols) && $offset < $length) {
3089 if ($row == $rows && $col == 0) {
3090 $this->dmtx_place_1($mtx, $rows, $cols, $data[$offset++]);
3091 }
else if ($row == $rows - 2 && $col == 0 && $cols % 4 != 0) {
3092 $this->dmtx_place_2($mtx, $rows, $cols, $data[$offset++]);
3093 }
else if ($row == $rows - 2 && $col == 0 && $cols % 8 == 4) {
3094 $this->dmtx_place_3($mtx, $rows, $cols, $data[$offset++]);
3095 }
else if ($row == $rows + 4 && $col == 2 && $cols % 8 == 0) {
3096 $this->dmtx_place_4($mtx, $rows, $cols, $data[$offset++]);
3099 while ($row >= 0 && $col < $cols && $offset < $length) {
3100 if ($row < $rows && $col >= 0 && is_null($mtx[$row][$col])) {
3101 $b = $data[$offset++];
3102 $this->dmtx_place_0($mtx, $rows, $cols, $row, $col, $b);
3110 while ($row < $rows && $col >= 0 && $offset < $length) {
3111 if ($row >= 0 && $col < $cols && is_null($mtx[$row][$col])) {
3112 $b = $data[$offset++];
3113 $this->dmtx_place_0($mtx, $rows, $cols, $row, $col, $b);
3123 private function dmtx_place_1(&$matrix, $rows, $cols, $b) {
3124 $matrix[$rows - 1][0] = (($b & 0x80) ? 1 : 0);
3125 $matrix[$rows - 1][1] = (($b & 0x40) ? 1 : 0);
3126 $matrix[$rows - 1][2] = (($b & 0x20) ? 1 : 0);
3127 $matrix[0][$cols - 2] = (($b & 0x10) ? 1 : 0);
3128 $matrix[0][$cols - 1] = (($b & 0x08) ? 1 : 0);
3129 $matrix[1][$cols - 1] = (($b & 0x04) ? 1 : 0);
3130 $matrix[2][$cols - 1] = (($b & 0x02) ? 1 : 0);
3131 $matrix[3][$cols - 1] = (($b & 0x01) ? 1 : 0);
3134 private function dmtx_place_2(&$matrix, $rows, $cols, $b) {
3135 $matrix[$rows - 3][0] = (($b & 0x80) ? 1 : 0);
3136 $matrix[$rows - 2][0] = (($b & 0x40) ? 1 : 0);
3137 $matrix[$rows - 1][0] = (($b & 0x20) ? 1 : 0);
3138 $matrix[0][$cols - 4] = (($b & 0x10) ? 1 : 0);
3139 $matrix[0][$cols - 3] = (($b & 0x08) ? 1 : 0);
3140 $matrix[0][$cols - 2] = (($b & 0x04) ? 1 : 0);
3141 $matrix[0][$cols - 1] = (($b & 0x02) ? 1 : 0);
3142 $matrix[1][$cols - 1] = (($b & 0x01) ? 1 : 0);
3145 private function dmtx_place_3(&$matrix, $rows, $cols, $b) {
3146 $matrix[$rows - 3][0] = (($b & 0x80) ? 1 : 0);
3147 $matrix[$rows - 2][0] = (($b & 0x40) ? 1 : 0);
3148 $matrix[$rows - 1][0] = (($b & 0x20) ? 1 : 0);
3149 $matrix[0][$cols - 2] = (($b & 0x10) ? 1 : 0);
3150 $matrix[0][$cols - 1] = (($b & 0x08) ? 1 : 0);
3151 $matrix[1][$cols - 1] = (($b & 0x04) ? 1 : 0);
3152 $matrix[2][$cols - 1] = (($b & 0x02) ? 1 : 0);
3153 $matrix[3][$cols - 1] = (($b & 0x01) ? 1 : 0);
3156 private function dmtx_place_4(&$matrix, $rows, $cols, $b) {
3157 $matrix[$rows - 1][ 0] = (($b & 0x80) ? 1 : 0);
3158 $matrix[$rows - 1][$cols - 1] = (($b & 0x40) ? 1 : 0);
3159 $matrix[ 0][$cols - 3] = (($b & 0x20) ? 1 : 0);
3160 $matrix[ 0][$cols - 2] = (($b & 0x10) ? 1 : 0);
3161 $matrix[ 0][$cols - 1] = (($b & 0x08) ? 1 : 0);
3162 $matrix[ 1][$cols - 3] = (($b & 0x04) ? 1 : 0);
3163 $matrix[ 1][$cols - 2] = (($b & 0x02) ? 1 : 0);
3164 $matrix[ 1][$cols - 1] = (($b & 0x01) ? 1 : 0);
3167 private function dmtx_place_0(&$matrix, $rows, $cols, $row, $col, $b) {
3168 $this->dmtx_place_b($matrix, $rows, $cols, $row-2, $col-2, $b & 0x80);
3169 $this->dmtx_place_b($matrix, $rows, $cols, $row-2, $col-1, $b & 0x40);
3170 $this->dmtx_place_b($matrix, $rows, $cols, $row-1, $col-2, $b & 0x20);
3171 $this->dmtx_place_b($matrix, $rows, $cols, $row-1, $col-1, $b & 0x10);
3172 $this->dmtx_place_b($matrix, $rows, $cols, $row-1, $col-0, $b & 0x08);
3173 $this->dmtx_place_b($matrix, $rows, $cols, $row-0, $col-2, $b & 0x04);
3174 $this->dmtx_place_b($matrix, $rows, $cols, $row-0, $col-1, $b & 0x02);
3175 $this->dmtx_place_b($matrix, $rows, $cols, $row-0, $col-0, $b & 0x01);
3178 private function dmtx_place_b(&$matrix, $rows, $cols, $row, $col, $b) {
3181 $col += (4 - (($rows + 4) % 8));
3185 $row += (4 - (($cols + 4) % 8));
3187 $matrix[$row][$col] = ($b ? 1 : 0);
3202 private $dmtx_ec_params = array(
3203 array( 3, 5, 1, 3, 0, 0, 1, 1, 8, 8 ),
3204 array( 5, 7, 1, 5, 0, 0, 1, 1, 10, 10 ),
3205 array( 8, 10, 1, 8, 0, 0, 1, 1, 12, 12 ),
3206 array( 12, 12, 1, 12, 0, 0, 1, 1, 14, 14 ),
3207 array( 18, 14, 1, 18, 0, 0, 1, 1, 16, 16 ),
3208 array( 22, 18, 1, 22, 0, 0, 1, 1, 18, 18 ),
3209 array( 30, 20, 1, 30, 0, 0, 1, 1, 20, 20 ),
3210 array( 36, 24, 1, 36, 0, 0, 1, 1, 22, 22 ),
3211 array( 44, 28, 1, 44, 0, 0, 1, 1, 24, 24 ),
3212 array( 62, 36, 1, 62, 0, 0, 2, 2, 14, 14 ),
3213 array( 86, 42, 1, 86, 0, 0, 2, 2, 16, 16 ),
3214 array( 114, 48, 1, 114, 0, 0, 2, 2, 18, 18 ),
3215 array( 144, 56, 1, 144, 0, 0, 2, 2, 20, 20 ),
3216 array( 174, 68, 1, 174, 0, 0, 2, 2, 22, 22 ),
3217 array( 204, 42, 2, 102, 0, 0, 2, 2, 24, 24 ),
3218 array( 280, 56, 2, 140, 0, 0, 4, 4, 14, 14 ),
3219 array( 368, 36, 4, 92, 0, 0, 4, 4, 16, 16 ),
3220 array( 456, 48, 4, 114, 0, 0, 4, 4, 18, 18 ),
3221 array( 576, 56, 4, 144, 0, 0, 4, 4, 20, 20 ),
3222 array( 696, 68, 4, 174, 0, 0, 4, 4, 22, 22 ),
3223 array( 816, 56, 6, 136, 0, 0, 4, 4, 24, 24 ),
3224 array( 1050, 68, 6, 175, 0, 0, 6, 6, 18, 18 ),
3225 array( 1304, 62, 8, 163, 0, 0, 6, 6, 20, 20 ),
3226 array( 1558, 62, 8, 156, 2, 155, 6, 6, 22, 22 ),
3227 array( 5, 7, 1, 5, 0, 0, 1, 1, 6, 16 ),
3228 array( 10, 11, 1, 10, 0, 0, 1, 2, 6, 14 ),
3229 array( 16, 14, 1, 16, 0, 0, 1, 1, 10, 24 ),
3230 array( 22, 18, 1, 22, 0, 0, 1, 2, 10, 16 ),
3231 array( 32, 24, 1, 32, 0, 0, 1, 2, 14, 16 ),
3232 array( 49, 28, 1, 49, 0, 0, 1, 2, 14, 22 ),
3235 private $dmtx_ec_polynomials = array(
3237 0, 235, 207, 210, 244, 15
3240 0, 177, 30, 214, 218, 42, 197, 28
3243 0, 199, 50, 150, 120, 237, 131, 172, 83, 243, 55
3246 0, 213, 173, 212, 156, 103, 109, 174, 242, 215, 12, 66
3249 0, 168, 142, 35, 173, 94, 185, 107, 199, 74, 194, 233, 78
3252 0, 83, 171, 33, 39, 8, 12, 248,
3253 27, 38, 84, 93, 246, 173, 105
3256 0, 164, 9, 244, 69, 177, 163, 161, 231, 94,
3257 250, 199, 220, 253, 164, 103, 142, 61, 171
3260 0, 127, 33, 146, 23, 79, 25, 193, 122, 209, 233,
3261 230, 164, 1, 109, 184, 149, 38, 201, 61, 210
3264 0, 65, 141, 245, 31, 183, 242, 236, 177, 127, 225, 106,
3265 22, 131, 20, 202, 22, 106, 137, 103, 231, 215, 136, 85, 45
3268 0, 150, 32, 109, 149, 239, 213, 198, 48, 94,
3269 50, 12, 195, 167, 130, 196, 253, 99, 166, 239,
3270 222, 146, 190, 245, 184, 173, 125, 17, 151
3273 0, 57, 86, 187, 69, 140, 153, 31, 66, 135, 67, 248, 84,
3274 90, 81, 219, 197, 2, 1, 39, 16, 75, 229, 20, 51, 252,
3275 108, 213, 181, 183, 87, 111, 77, 232, 168, 176, 156
3278 0, 225, 38, 225, 148, 192, 254, 141, 11, 82, 237,
3279 81, 24, 13, 122, 0, 106, 167, 13, 207, 160, 88,
3280 203, 38, 142, 84, 66, 3, 168, 102, 156, 1, 200,
3281 88, 60, 233, 134, 115, 114, 234, 90, 65, 138
3284 0, 114, 69, 122, 30, 94, 11, 66, 230, 132, 73, 145, 137,
3285 135, 79, 214, 33, 12, 220, 142, 213, 136, 124, 215, 166,
3286 9, 222, 28, 154, 132, 4, 100, 170, 145, 59, 164, 215, 17,
3287 249, 102, 249, 134, 128, 5, 245, 131, 127, 221, 156
3290 0, 29, 179, 99, 149, 159, 72, 125, 22, 55, 60, 217,
3291 176, 156, 90, 43, 80, 251, 235, 128, 169, 254, 134,
3292 249, 42, 121, 118, 72, 128, 129, 232, 37, 15, 24, 221,
3293 143, 115, 131, 40, 113, 254, 19, 123, 246, 68, 166,
3294 66, 118, 142, 47, 51, 195, 242, 249, 131, 38, 66
3297 0, 182, 133, 162, 126, 236, 58, 172, 163, 53, 121, 159, 2,
3298 166, 137, 234, 158, 195, 164, 77, 228, 226, 145, 91, 180,
3299 232, 23, 241, 132, 135, 206, 184, 14, 6, 66, 238, 83, 100,
3300 111, 85, 202, 91, 156, 68, 218, 57, 83, 222, 188, 25, 179,
3301 144, 169, 164, 82, 154, 103, 89, 42, 141, 175, 32, 168
3304 0, 33, 79, 190, 245, 91, 221, 233, 25, 24, 6, 144,
3305 151, 121, 186, 140, 127, 45, 153, 250, 183, 70, 131,
3306 198, 17, 89, 245, 121, 51, 140, 252, 203, 82, 83, 233,
3307 152, 220, 155, 18, 230, 210, 94, 32, 200, 197, 192,
3308 194, 202, 129, 10, 237, 198, 94, 176, 36, 40, 139,
3309 201, 132, 219, 34, 56, 113, 52, 20, 34, 247, 15, 51
3313 private $dmtx_log = array(
3314 0, 0, 1, 240, 2, 225, 241, 53,
3315 3, 38, 226, 133, 242, 43, 54, 210,
3316 4, 195, 39, 114, 227, 106, 134, 28,
3317 243, 140, 44, 23, 55, 118, 211, 234,
3318 5, 219, 196, 96, 40, 222, 115, 103,
3319 228, 78, 107, 125, 135, 8, 29, 162,
3320 244, 186, 141, 180, 45, 99, 24, 49,
3321 56, 13, 119, 153, 212, 199, 235, 91,
3322 6, 76, 220, 217, 197, 11, 97, 184,
3323 41, 36, 223, 253, 116, 138, 104, 193,
3324 229, 86, 79, 171, 108, 165, 126, 145,
3325 136, 34, 9, 74, 30, 32, 163, 84,
3326 245, 173, 187, 204, 142, 81, 181, 190,
3327 46, 88, 100, 159, 25, 231, 50, 207,
3328 57, 147, 14, 67, 120, 128, 154, 248,
3329 213, 167, 200, 63, 236, 110, 92, 176,
3330 7, 161, 77, 124, 221, 102, 218, 95,
3331 198, 90, 12, 152, 98, 48, 185, 179,
3332 42, 209, 37, 132, 224, 52, 254, 239,
3333 117, 233, 139, 22, 105, 27, 194, 113,
3334 230, 206, 87, 158, 80, 189, 172, 203,
3335 109, 175, 166, 62, 127, 247, 146, 66,
3336 137, 192, 35, 252, 10, 183, 75, 216,
3337 31, 83, 33, 73, 164, 144, 85, 170,
3338 246, 65, 174, 61, 188, 202, 205, 157,
3339 143, 169, 82, 72, 182, 215, 191, 251,
3340 47, 178, 89, 151, 101, 94, 160, 123,
3341 26, 112, 232, 21, 51, 238, 208, 131,
3342 58, 69, 148, 18, 15, 16, 68, 17,
3343 121, 149, 129, 19, 155, 59, 249, 70,
3344 214, 250, 168, 71, 201, 156, 64, 60,
3345 237, 130, 111, 20, 93, 122, 177, 150,
3348 private $dmtx_exp = array(
3349 1, 2, 4, 8, 16, 32, 64, 128,
3350 45, 90, 180, 69, 138, 57, 114, 228,
3351 229, 231, 227, 235, 251, 219, 155, 27,
3352 54, 108, 216, 157, 23, 46, 92, 184,
3353 93, 186, 89, 178, 73, 146, 9, 18,
3354 36, 72, 144, 13, 26, 52, 104, 208,
3355 141, 55, 110, 220, 149, 7, 14, 28,
3356 56, 112, 224, 237, 247, 195, 171, 123,
3357 246, 193, 175, 115, 230, 225, 239, 243,
3358 203, 187, 91, 182, 65, 130, 41, 82,
3359 164, 101, 202, 185, 95, 190, 81, 162,
3360 105, 210, 137, 63, 126, 252, 213, 135,
3361 35, 70, 140, 53, 106, 212, 133, 39,
3362 78, 156, 21, 42, 84, 168, 125, 250,
3363 217, 159, 19, 38, 76, 152, 29, 58,
3364 116, 232, 253, 215, 131, 43, 86, 172,
3365 117, 234, 249, 223, 147, 11, 22, 44,
3366 88, 176, 77, 154, 25, 50, 100, 200,
3367 189, 87, 174, 113, 226, 233, 255, 211,
3368 139, 59, 118, 236, 245, 199, 163, 107,
3369 214, 129, 47, 94, 188, 85, 170, 121,
3370 242, 201, 191, 83, 166, 97, 194, 169,
3371 127, 254, 209, 143, 51, 102, 204, 181,
3372 71, 142, 49, 98, 196, 165, 103, 206,
3373 177, 79, 158, 17, 34, 68, 136, 61,
3374 122, 244, 197, 167, 99, 198, 161, 111,
3375 222, 145, 15, 30, 60, 120, 240, 205,
3376 183, 67, 134, 33, 66, 132, 37, 74,
3377 148, 5, 10, 20, 40, 80, 160, 109,
3378 218, 153, 31, 62, 124, 248, 221, 151,
3379 3, 6, 12, 24, 48, 96, 192, 173,
3380 119, 238, 241, 207, 179, 75, 150, 1,