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