]> git.wh0rd.org - tt-rss.git/blame - lib/phpqrcode/qrspec.php
strip_harmful_tags: remove data- attributes
[tt-rss.git] / lib / phpqrcode / qrspec.php
CommitLineData
fb70f26e
AD
1<?php\r
2/*\r
3 * PHP QR Code encoder\r
4 *\r
5 * QR Code specifications\r
6 *\r
7 * Based on libqrencode C library distributed under LGPL 2.1\r
8 * Copyright (C) 2006, 2007, 2008, 2009 Kentaro Fukuchi <fukuchi@megaui.net>\r
9 *\r
10 * PHP QR Code is distributed under LGPL 3\r
11 * Copyright (C) 2010 Dominik Dzienia <deltalab at poczta dot fm>\r
12 *\r
13 * The following data / specifications are taken from\r
14 * "Two dimensional symbol -- QR-code -- Basic Specification" (JIS X0510:2004)\r
15 * or\r
16 * "Automatic identification and data capture techniques -- \r
17 * QR Code 2005 bar code symbology specification" (ISO/IEC 18004:2006)\r
18 *\r
19 * This library is free software; you can redistribute it and/or\r
20 * modify it under the terms of the GNU Lesser General Public\r
21 * License as published by the Free Software Foundation; either\r
22 * version 3 of the License, or any later version.\r
23 *\r
24 * This library is distributed in the hope that it will be useful,\r
25 * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
26 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\r
27 * Lesser General Public License for more details.\r
28 *\r
29 * You should have received a copy of the GNU Lesser General Public\r
30 * License along with this library; if not, write to the Free Software\r
31 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA\r
32 */\r
33 \r
34 define('QRSPEC_VERSION_MAX', 40);\r
35 define('QRSPEC_WIDTH_MAX', 177);\r
36\r
37 define('QRCAP_WIDTH', 0);\r
38 define('QRCAP_WORDS', 1);\r
39 define('QRCAP_REMINDER', 2);\r
40 define('QRCAP_EC', 3);\r
41\r
42 class QRspec {\r
43 \r
44 public static $capacity = array(\r
45 array( 0, 0, 0, array( 0, 0, 0, 0)),\r
46 array( 21, 26, 0, array( 7, 10, 13, 17)), // 1\r
47 array( 25, 44, 7, array( 10, 16, 22, 28)),\r
48 array( 29, 70, 7, array( 15, 26, 36, 44)),\r
49 array( 33, 100, 7, array( 20, 36, 52, 64)),\r
50 array( 37, 134, 7, array( 26, 48, 72, 88)), // 5\r
51 array( 41, 172, 7, array( 36, 64, 96, 112)),\r
52 array( 45, 196, 0, array( 40, 72, 108, 130)),\r
53 array( 49, 242, 0, array( 48, 88, 132, 156)),\r
54 array( 53, 292, 0, array( 60, 110, 160, 192)),\r
55 array( 57, 346, 0, array( 72, 130, 192, 224)), //10\r
56 array( 61, 404, 0, array( 80, 150, 224, 264)),\r
57 array( 65, 466, 0, array( 96, 176, 260, 308)),\r
58 array( 69, 532, 0, array( 104, 198, 288, 352)),\r
59 array( 73, 581, 3, array( 120, 216, 320, 384)),\r
60 array( 77, 655, 3, array( 132, 240, 360, 432)), //15\r
61 array( 81, 733, 3, array( 144, 280, 408, 480)),\r
62 array( 85, 815, 3, array( 168, 308, 448, 532)),\r
63 array( 89, 901, 3, array( 180, 338, 504, 588)),\r
64 array( 93, 991, 3, array( 196, 364, 546, 650)),\r
65 array( 97, 1085, 3, array( 224, 416, 600, 700)), //20\r
66 array(101, 1156, 4, array( 224, 442, 644, 750)),\r
67 array(105, 1258, 4, array( 252, 476, 690, 816)),\r
68 array(109, 1364, 4, array( 270, 504, 750, 900)),\r
69 array(113, 1474, 4, array( 300, 560, 810, 960)),\r
70 array(117, 1588, 4, array( 312, 588, 870, 1050)), //25\r
71 array(121, 1706, 4, array( 336, 644, 952, 1110)),\r
72 array(125, 1828, 4, array( 360, 700, 1020, 1200)),\r
73 array(129, 1921, 3, array( 390, 728, 1050, 1260)),\r
74 array(133, 2051, 3, array( 420, 784, 1140, 1350)),\r
75 array(137, 2185, 3, array( 450, 812, 1200, 1440)), //30\r
76 array(141, 2323, 3, array( 480, 868, 1290, 1530)),\r
77 array(145, 2465, 3, array( 510, 924, 1350, 1620)),\r
78 array(149, 2611, 3, array( 540, 980, 1440, 1710)),\r
79 array(153, 2761, 3, array( 570, 1036, 1530, 1800)),\r
80 array(157, 2876, 0, array( 570, 1064, 1590, 1890)), //35\r
81 array(161, 3034, 0, array( 600, 1120, 1680, 1980)),\r
82 array(165, 3196, 0, array( 630, 1204, 1770, 2100)),\r
83 array(169, 3362, 0, array( 660, 1260, 1860, 2220)),\r
84 array(173, 3532, 0, array( 720, 1316, 1950, 2310)),\r
85 array(177, 3706, 0, array( 750, 1372, 2040, 2430)) //40\r
86 );\r
87 \r
88 //----------------------------------------------------------------------\r
89 public static function getDataLength($version, $level)\r
90 {\r
91 return self::$capacity[$version][QRCAP_WORDS] - self::$capacity[$version][QRCAP_EC][$level];\r
92 }\r
93 \r
94 //----------------------------------------------------------------------\r
95 public static function getECCLength($version, $level)\r
96 {\r
97 return self::$capacity[$version][QRCAP_EC][$level];\r
98 }\r
99 \r
100 //----------------------------------------------------------------------\r
101 public static function getWidth($version)\r
102 {\r
103 return self::$capacity[$version][QRCAP_WIDTH];\r
104 }\r
105 \r
106 //----------------------------------------------------------------------\r
107 public static function getRemainder($version)\r
108 {\r
109 return self::$capacity[$version][QRCAP_REMINDER];\r
110 }\r
111 \r
112 //----------------------------------------------------------------------\r
113 public static function getMinimumVersion($size, $level)\r
114 {\r
115\r
116 for($i=1; $i<= QRSPEC_VERSION_MAX; $i++) {\r
117 $words = self::$capacity[$i][QRCAP_WORDS] - self::$capacity[$i][QRCAP_EC][$level];\r
118 if($words >= $size) \r
119 return $i;\r
120 }\r
121\r
122 return -1;\r
123 }\r
124 \r
125 //######################################################################\r
126 \r
127 public static $lengthTableBits = array(\r
128 array(10, 12, 14),\r
129 array( 9, 11, 13),\r
130 array( 8, 16, 16),\r
131 array( 8, 10, 12)\r
132 );\r
133 \r
134 //----------------------------------------------------------------------\r
135 public static function lengthIndicator($mode, $version)\r
136 {\r
137 if ($mode == QR_MODE_STRUCTURE)\r
138 return 0;\r
139 \r
140 if ($version <= 9) {\r
141 $l = 0;\r
142 } else if ($version <= 26) {\r
143 $l = 1;\r
144 } else {\r
145 $l = 2;\r
146 }\r
147\r
148 return self::$lengthTableBits[$mode][$l];\r
149 }\r
150 \r
151 //----------------------------------------------------------------------\r
152 public static function maximumWords($mode, $version)\r
153 {\r
154 if($mode == QR_MODE_STRUCTURE) \r
155 return 3;\r
156 \r
157 if($version <= 9) {\r
158 $l = 0;\r
159 } else if($version <= 26) {\r
160 $l = 1;\r
161 } else {\r
162 $l = 2;\r
163 }\r
164\r
165 $bits = self::$lengthTableBits[$mode][$l];\r
166 $words = (1 << $bits) - 1;\r
167 \r
168 if($mode == QR_MODE_KANJI) {\r
169 $words *= 2; // the number of bytes is required\r
170 }\r
171\r
172 return $words;\r
173 }\r
174\r
175 // Error correction code -----------------------------------------------\r
176 // Table of the error correction code (Reed-Solomon block)\r
177 // See Table 12-16 (pp.30-36), JIS X0510:2004.\r
178\r
179 public static $eccTable = array(\r
180 array(array( 0, 0), array( 0, 0), array( 0, 0), array( 0, 0)),\r
181 array(array( 1, 0), array( 1, 0), array( 1, 0), array( 1, 0)), // 1\r
182 array(array( 1, 0), array( 1, 0), array( 1, 0), array( 1, 0)),\r
183 array(array( 1, 0), array( 1, 0), array( 2, 0), array( 2, 0)),\r
184 array(array( 1, 0), array( 2, 0), array( 2, 0), array( 4, 0)),\r
185 array(array( 1, 0), array( 2, 0), array( 2, 2), array( 2, 2)), // 5\r
186 array(array( 2, 0), array( 4, 0), array( 4, 0), array( 4, 0)),\r
187 array(array( 2, 0), array( 4, 0), array( 2, 4), array( 4, 1)),\r
188 array(array( 2, 0), array( 2, 2), array( 4, 2), array( 4, 2)),\r
189 array(array( 2, 0), array( 3, 2), array( 4, 4), array( 4, 4)),\r
190 array(array( 2, 2), array( 4, 1), array( 6, 2), array( 6, 2)), //10\r
191 array(array( 4, 0), array( 1, 4), array( 4, 4), array( 3, 8)),\r
192 array(array( 2, 2), array( 6, 2), array( 4, 6), array( 7, 4)),\r
193 array(array( 4, 0), array( 8, 1), array( 8, 4), array(12, 4)),\r
194 array(array( 3, 1), array( 4, 5), array(11, 5), array(11, 5)),\r
195 array(array( 5, 1), array( 5, 5), array( 5, 7), array(11, 7)), //15\r
196 array(array( 5, 1), array( 7, 3), array(15, 2), array( 3, 13)),\r
197 array(array( 1, 5), array(10, 1), array( 1, 15), array( 2, 17)),\r
198 array(array( 5, 1), array( 9, 4), array(17, 1), array( 2, 19)),\r
199 array(array( 3, 4), array( 3, 11), array(17, 4), array( 9, 16)),\r
200 array(array( 3, 5), array( 3, 13), array(15, 5), array(15, 10)), //20\r
201 array(array( 4, 4), array(17, 0), array(17, 6), array(19, 6)),\r
202 array(array( 2, 7), array(17, 0), array( 7, 16), array(34, 0)),\r
203 array(array( 4, 5), array( 4, 14), array(11, 14), array(16, 14)),\r
204 array(array( 6, 4), array( 6, 14), array(11, 16), array(30, 2)),\r
205 array(array( 8, 4), array( 8, 13), array( 7, 22), array(22, 13)), //25\r
206 array(array(10, 2), array(19, 4), array(28, 6), array(33, 4)),\r
207 array(array( 8, 4), array(22, 3), array( 8, 26), array(12, 28)),\r
208 array(array( 3, 10), array( 3, 23), array( 4, 31), array(11, 31)),\r
209 array(array( 7, 7), array(21, 7), array( 1, 37), array(19, 26)),\r
210 array(array( 5, 10), array(19, 10), array(15, 25), array(23, 25)), //30\r
211 array(array(13, 3), array( 2, 29), array(42, 1), array(23, 28)),\r
212 array(array(17, 0), array(10, 23), array(10, 35), array(19, 35)),\r
213 array(array(17, 1), array(14, 21), array(29, 19), array(11, 46)),\r
214 array(array(13, 6), array(14, 23), array(44, 7), array(59, 1)),\r
215 array(array(12, 7), array(12, 26), array(39, 14), array(22, 41)), //35\r
216 array(array( 6, 14), array( 6, 34), array(46, 10), array( 2, 64)),\r
217 array(array(17, 4), array(29, 14), array(49, 10), array(24, 46)),\r
218 array(array( 4, 18), array(13, 32), array(48, 14), array(42, 32)),\r
219 array(array(20, 4), array(40, 7), array(43, 22), array(10, 67)),\r
220 array(array(19, 6), array(18, 31), array(34, 34), array(20, 61)),//40\r
221 ); \r
222\r
223 //----------------------------------------------------------------------\r
224 // CACHEABLE!!!\r
225 \r
226 public static function getEccSpec($version, $level, array &$spec)\r
227 {\r
228 if (count($spec) < 5) {\r
229 $spec = array(0,0,0,0,0);\r
230 }\r
231\r
232 $b1 = self::$eccTable[$version][$level][0];\r
233 $b2 = self::$eccTable[$version][$level][1];\r
234 $data = self::getDataLength($version, $level);\r
235 $ecc = self::getECCLength($version, $level);\r
236\r
237 if($b2 == 0) {\r
238 $spec[0] = $b1;\r
239 $spec[1] = (int)($data / $b1);\r
240 $spec[2] = (int)($ecc / $b1);\r
241 $spec[3] = 0; \r
242 $spec[4] = 0;\r
243 } else {\r
244 $spec[0] = $b1;\r
245 $spec[1] = (int)($data / ($b1 + $b2));\r
246 $spec[2] = (int)($ecc / ($b1 + $b2));\r
247 $spec[3] = $b2;\r
248 $spec[4] = $spec[1] + 1;\r
249 }\r
250 }\r
251\r
252 // Alignment pattern ---------------------------------------------------\r
253\r
254 // Positions of alignment patterns.\r
255 // This array includes only the second and the third position of the \r
256 // alignment patterns. Rest of them can be calculated from the distance \r
257 // between them.\r
258 \r
259 // See Table 1 in Appendix E (pp.71) of JIS X0510:2004.\r
260 \r
261 public static $alignmentPattern = array( \r
262 array( 0, 0),\r
263 array( 0, 0), array(18, 0), array(22, 0), array(26, 0), array(30, 0), // 1- 5\r
264 array(34, 0), array(22, 38), array(24, 42), array(26, 46), array(28, 50), // 6-10\r
265 array(30, 54), array(32, 58), array(34, 62), array(26, 46), array(26, 48), //11-15\r
266 array(26, 50), array(30, 54), array(30, 56), array(30, 58), array(34, 62), //16-20\r
267 array(28, 50), array(26, 50), array(30, 54), array(28, 54), array(32, 58), //21-25\r
268 array(30, 58), array(34, 62), array(26, 50), array(30, 54), array(26, 52), //26-30\r
269 array(30, 56), array(34, 60), array(30, 58), array(34, 62), array(30, 54), //31-35\r
270 array(24, 50), array(28, 54), array(32, 58), array(26, 54), array(30, 58), //35-40\r
271 ); \r
272\r
273 \r
274 /** --------------------------------------------------------------------\r
275 * Put an alignment marker.\r
276 * @param frame\r
277 * @param width\r
278 * @param ox,oy center coordinate of the pattern\r
279 */\r
280 public static function putAlignmentMarker(array &$frame, $ox, $oy)\r
281 {\r
282 $finder = array(\r
283 "\xa1\xa1\xa1\xa1\xa1",\r
284 "\xa1\xa0\xa0\xa0\xa1",\r
285 "\xa1\xa0\xa1\xa0\xa1",\r
286 "\xa1\xa0\xa0\xa0\xa1",\r
287 "\xa1\xa1\xa1\xa1\xa1"\r
288 ); \r
289 \r
290 $yStart = $oy-2; \r
291 $xStart = $ox-2;\r
292 \r
293 for($y=0; $y<5; $y++) {\r
294 QRstr::set($frame, $xStart, $yStart+$y, $finder[$y]);\r
295 }\r
296 }\r
297\r
298 //----------------------------------------------------------------------\r
299 public static function putAlignmentPattern($version, &$frame, $width)\r
300 {\r
301 if($version < 2)\r
302 return;\r
303\r
304 $d = self::$alignmentPattern[$version][1] - self::$alignmentPattern[$version][0];\r
305 if($d < 0) {\r
306 $w = 2;\r
307 } else {\r
308 $w = (int)(($width - self::$alignmentPattern[$version][0]) / $d + 2);\r
309 }\r
310\r
311 if($w * $w - 3 == 1) {\r
312 $x = self::$alignmentPattern[$version][0];\r
313 $y = self::$alignmentPattern[$version][0];\r
314 self::putAlignmentMarker($frame, $x, $y);\r
315 return;\r
316 }\r
317\r
318 $cx = self::$alignmentPattern[$version][0];\r
319 for($x=1; $x<$w - 1; $x++) {\r
320 self::putAlignmentMarker($frame, 6, $cx);\r
321 self::putAlignmentMarker($frame, $cx, 6);\r
322 $cx += $d;\r
323 }\r
324\r
325 $cy = self::$alignmentPattern[$version][0];\r
326 for($y=0; $y<$w-1; $y++) {\r
327 $cx = self::$alignmentPattern[$version][0];\r
328 for($x=0; $x<$w-1; $x++) {\r
329 self::putAlignmentMarker($frame, $cx, $cy);\r
330 $cx += $d;\r
331 }\r
332 $cy += $d;\r
333 }\r
334 }\r
335\r
336 // Version information pattern -----------------------------------------\r
337\r
338 // Version information pattern (BCH coded).\r
339 // See Table 1 in Appendix D (pp.68) of JIS X0510:2004.\r
340 \r
341 // size: [QRSPEC_VERSION_MAX - 6]\r
342 \r
343 public static $versionPattern = array(\r
344 0x07c94, 0x085bc, 0x09a99, 0x0a4d3, 0x0bbf6, 0x0c762, 0x0d847, 0x0e60d,\r
345 0x0f928, 0x10b78, 0x1145d, 0x12a17, 0x13532, 0x149a6, 0x15683, 0x168c9,\r
346 0x177ec, 0x18ec4, 0x191e1, 0x1afab, 0x1b08e, 0x1cc1a, 0x1d33f, 0x1ed75,\r
347 0x1f250, 0x209d5, 0x216f0, 0x228ba, 0x2379f, 0x24b0b, 0x2542e, 0x26a64,\r
348 0x27541, 0x28c69\r
349 );\r
350\r
351 //----------------------------------------------------------------------\r
352 public static function getVersionPattern($version)\r
353 {\r
354 if($version < 7 || $version > QRSPEC_VERSION_MAX)\r
355 return 0;\r
356\r
357 return self::$versionPattern[$version -7];\r
358 }\r
359\r
360 // Format information --------------------------------------------------\r
361 // See calcFormatInfo in tests/test_qrspec.c (orginal qrencode c lib)\r
362 \r
363 public static $formatInfo = array(\r
364 array(0x77c4, 0x72f3, 0x7daa, 0x789d, 0x662f, 0x6318, 0x6c41, 0x6976),\r
365 array(0x5412, 0x5125, 0x5e7c, 0x5b4b, 0x45f9, 0x40ce, 0x4f97, 0x4aa0),\r
366 array(0x355f, 0x3068, 0x3f31, 0x3a06, 0x24b4, 0x2183, 0x2eda, 0x2bed),\r
367 array(0x1689, 0x13be, 0x1ce7, 0x19d0, 0x0762, 0x0255, 0x0d0c, 0x083b)\r
368 );\r
369\r
370 public static function getFormatInfo($mask, $level)\r
371 {\r
372 if($mask < 0 || $mask > 7)\r
373 return 0;\r
374 \r
375 if($level < 0 || $level > 3)\r
376 return 0; \r
377\r
378 return self::$formatInfo[$level][$mask];\r
379 }\r
380\r
381 // Frame ---------------------------------------------------------------\r
382 // Cache of initial frames.\r
383 \r
384 public static $frames = array();\r
385\r
386 /** --------------------------------------------------------------------\r
387 * Put a finder pattern.\r
388 * @param frame\r
389 * @param width\r
390 * @param ox,oy upper-left coordinate of the pattern\r
391 */\r
392 public static function putFinderPattern(&$frame, $ox, $oy)\r
393 {\r
394 $finder = array(\r
395 "\xc1\xc1\xc1\xc1\xc1\xc1\xc1",\r
396 "\xc1\xc0\xc0\xc0\xc0\xc0\xc1",\r
397 "\xc1\xc0\xc1\xc1\xc1\xc0\xc1",\r
398 "\xc1\xc0\xc1\xc1\xc1\xc0\xc1",\r
399 "\xc1\xc0\xc1\xc1\xc1\xc0\xc1",\r
400 "\xc1\xc0\xc0\xc0\xc0\xc0\xc1",\r
401 "\xc1\xc1\xc1\xc1\xc1\xc1\xc1"\r
402 ); \r
403 \r
404 for($y=0; $y<7; $y++) {\r
405 QRstr::set($frame, $ox, $oy+$y, $finder[$y]);\r
406 }\r
407 }\r
408\r
409 //----------------------------------------------------------------------\r
410 public static function createFrame($version)\r
411 {\r
412 $width = self::$capacity[$version][QRCAP_WIDTH];\r
413 $frameLine = str_repeat ("\0", $width);\r
414 $frame = array_fill(0, $width, $frameLine);\r
415\r
416 // Finder pattern\r
417 self::putFinderPattern($frame, 0, 0);\r
418 self::putFinderPattern($frame, $width - 7, 0);\r
419 self::putFinderPattern($frame, 0, $width - 7);\r
420 \r
421 // Separator\r
422 $yOffset = $width - 7;\r
423 \r
424 for($y=0; $y<7; $y++) {\r
425 $frame[$y][7] = "\xc0";\r
426 $frame[$y][$width - 8] = "\xc0";\r
427 $frame[$yOffset][7] = "\xc0";\r
428 $yOffset++;\r
429 }\r
430 \r
431 $setPattern = str_repeat("\xc0", 8);\r
432 \r
433 QRstr::set($frame, 0, 7, $setPattern);\r
434 QRstr::set($frame, $width-8, 7, $setPattern);\r
435 QRstr::set($frame, 0, $width - 8, $setPattern);\r
436 \r
437 // Format info\r
438 $setPattern = str_repeat("\x84", 9);\r
439 QRstr::set($frame, 0, 8, $setPattern);\r
440 QRstr::set($frame, $width - 8, 8, $setPattern, 8);\r
441 \r
442 $yOffset = $width - 8;\r
443\r
444 for($y=0; $y<8; $y++,$yOffset++) {\r
445 $frame[$y][8] = "\x84";\r
446 $frame[$yOffset][8] = "\x84";\r
447 }\r
448\r
449 // Timing pattern \r
450 \r
451 for($i=1; $i<$width-15; $i++) {\r
452 $frame[6][7+$i] = chr(0x90 | ($i & 1));\r
453 $frame[7+$i][6] = chr(0x90 | ($i & 1));\r
454 }\r
455 \r
456 // Alignment pattern \r
457 self::putAlignmentPattern($version, $frame, $width);\r
458 \r
459 // Version information \r
460 if($version >= 7) {\r
461 $vinf = self::getVersionPattern($version);\r
462\r
463 $v = $vinf;\r
464 \r
465 for($x=0; $x<6; $x++) {\r
466 for($y=0; $y<3; $y++) {\r
467 $frame[($width - 11)+$y][$x] = chr(0x88 | ($v & 1));\r
468 $v = $v >> 1;\r
469 }\r
470 }\r
471\r
472 $v = $vinf;\r
473 for($y=0; $y<6; $y++) {\r
474 for($x=0; $x<3; $x++) {\r
475 $frame[$y][$x+($width - 11)] = chr(0x88 | ($v & 1));\r
476 $v = $v >> 1;\r
477 }\r
478 }\r
479 }\r
480 \r
481 // and a little bit... \r
482 $frame[$width - 8][8] = "\x81";\r
483 \r
484 return $frame;\r
485 }\r
486\r
487 //----------------------------------------------------------------------\r
488 public static function debug($frame, $binary_mode = false)\r
489 {\r
490 if ($binary_mode) {\r
491 \r
492 foreach ($frame as &$frameLine) {\r
493 $frameLine = join('<span class="m">&nbsp;&nbsp;</span>', explode('0', $frameLine));\r
494 $frameLine = join('&#9608;&#9608;', explode('1', $frameLine));\r
495 }\r
496 \r
497 ?>\r
498 <style>\r
499 .m { background-color: white; }\r
500 </style>\r
501 <?php\r
502 echo '<pre><tt><br/ ><br/ ><br/ >&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;';\r
503 echo join("<br/ >&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;", $frame);\r
504 echo '</tt></pre><br/ ><br/ ><br/ ><br/ ><br/ ><br/ >';\r
505 \r
506 } else {\r
507 \r
508 foreach ($frame as &$frameLine) {\r
509 $frameLine = join('<span class="m">&nbsp;</span>', explode("\xc0", $frameLine));\r
510 $frameLine = join('<span class="m">&#9618;</span>', explode("\xc1", $frameLine));\r
511 $frameLine = join('<span class="p">&nbsp;</span>', explode("\xa0", $frameLine));\r
512 $frameLine = join('<span class="p">&#9618;</span>', explode("\xa1", $frameLine));\r
513 $frameLine = join('<span class="s">&#9671;</span>', explode("\x84", $frameLine)); //format 0\r
514 $frameLine = join('<span class="s">&#9670;</span>', explode("\x85", $frameLine)); //format 1\r
515 $frameLine = join('<span class="x">&#9762;</span>', explode("\x81", $frameLine)); //special bit\r
516 $frameLine = join('<span class="c">&nbsp;</span>', explode("\x90", $frameLine)); //clock 0\r
517 $frameLine = join('<span class="c">&#9719;</span>', explode("\x91", $frameLine)); //clock 1\r
518 $frameLine = join('<span class="f">&nbsp;</span>', explode("\x88", $frameLine)); //version\r
519 $frameLine = join('<span class="f">&#9618;</span>', explode("\x89", $frameLine)); //version\r
520 $frameLine = join('&#9830;', explode("\x01", $frameLine));\r
521 $frameLine = join('&#8901;', explode("\0", $frameLine));\r
522 }\r
523 \r
524 ?>\r
525 <style>\r
526 .p { background-color: yellow; }\r
527 .m { background-color: #00FF00; }\r
528 .s { background-color: #FF0000; }\r
529 .c { background-color: aqua; }\r
530 .x { background-color: pink; }\r
531 .f { background-color: gold; }\r
532 </style>\r
533 <?php\r
534 echo "<pre><tt>";\r
535 echo join("<br/ >", $frame);\r
536 echo "</tt></pre>";\r
537 \r
538 }\r
539 }\r
540\r
541 //----------------------------------------------------------------------\r
542 public static function serial($frame)\r
543 {\r
544 return gzcompress(join("\n", $frame), 9);\r
545 }\r
546 \r
547 //----------------------------------------------------------------------\r
548 public static function unserial($code)\r
549 {\r
550 return explode("\n", gzuncompress($code));\r
551 }\r
552 \r
553 //----------------------------------------------------------------------\r
554 public static function newFrame($version)\r
555 {\r
556 if($version < 1 || $version > QRSPEC_VERSION_MAX) \r
557 return null;\r
558\r
559 if(!isset(self::$frames[$version])) {\r
560 \r
561 $fileName = QR_CACHE_DIR.'frame_'.$version.'.dat';\r
562 \r
563 if (QR_CACHEABLE) {\r
564 if (file_exists($fileName)) {\r
565 self::$frames[$version] = self::unserial(file_get_contents($fileName));\r
566 } else {\r
567 self::$frames[$version] = self::createFrame($version);\r
568 file_put_contents($fileName, self::serial(self::$frames[$version]));\r
569 }\r
570 } else {\r
571 self::$frames[$version] = self::createFrame($version);\r
572 }\r
573 }\r
574 \r
575 if(is_null(self::$frames[$version]))\r
576 return null;\r
577\r
578 return self::$frames[$version];\r
579 }\r
580\r
581 //----------------------------------------------------------------------\r
582 public static function rsBlockNum($spec) { return $spec[0] + $spec[3]; }\r
583 public static function rsBlockNum1($spec) { return $spec[0]; }\r
584 public static function rsDataCodes1($spec) { return $spec[1]; }\r
585 public static function rsEccCodes1($spec) { return $spec[2]; }\r
586 public static function rsBlockNum2($spec) { return $spec[3]; }\r
587 public static function rsDataCodes2($spec) { return $spec[4]; }\r
588 public static function rsEccCodes2($spec) { return $spec[2]; }\r
589 public static function rsDataLength($spec) { return ($spec[0] * $spec[1]) + ($spec[3] * $spec[4]); }\r
590 public static function rsEccLength($spec) { return ($spec[0] + $spec[3]) * $spec[2]; }\r
591 \r
592 }