]> git.wh0rd.org - tt-rss.git/blame - lib/phpqrcode/qrsplit.php
pngcrush.sh
[tt-rss.git] / lib / phpqrcode / qrsplit.php
CommitLineData
fb70f26e
AD
1<?php\r
2/*\r
3 * PHP QR Code encoder\r
4 *\r
5 * Input splitting classes\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 class QRsplit {\r
34\r
35 public $dataStr = '';\r
36 public $input;\r
37 public $modeHint;\r
38\r
39 //----------------------------------------------------------------------\r
40 public function __construct($dataStr, $input, $modeHint) \r
41 {\r
42 $this->dataStr = $dataStr;\r
43 $this->input = $input;\r
44 $this->modeHint = $modeHint;\r
45 }\r
46 \r
47 //----------------------------------------------------------------------\r
48 public static function isdigitat($str, $pos)\r
49 { \r
50 if ($pos >= strlen($str))\r
51 return false;\r
52 \r
53 return ((ord($str[$pos]) >= ord('0'))&&(ord($str[$pos]) <= ord('9')));\r
54 }\r
55 \r
56 //----------------------------------------------------------------------\r
57 public static function isalnumat($str, $pos)\r
58 {\r
59 if ($pos >= strlen($str))\r
60 return false;\r
61 \r
62 return (QRinput::lookAnTable(ord($str[$pos])) >= 0);\r
63 }\r
64\r
65 //----------------------------------------------------------------------\r
66 public function identifyMode($pos)\r
67 {\r
68 if ($pos >= strlen($this->dataStr)) \r
69 return QR_MODE_NUL;\r
70 \r
71 $c = $this->dataStr[$pos];\r
72 \r
73 if(self::isdigitat($this->dataStr, $pos)) {\r
74 return QR_MODE_NUM;\r
75 } else if(self::isalnumat($this->dataStr, $pos)) {\r
76 return QR_MODE_AN;\r
77 } else if($this->modeHint == QR_MODE_KANJI) {\r
78 \r
79 if ($pos+1 < strlen($this->dataStr)) \r
80 {\r
81 $d = $this->dataStr[$pos+1];\r
82 $word = (ord($c) << 8) | ord($d);\r
83 if(($word >= 0x8140 && $word <= 0x9ffc) || ($word >= 0xe040 && $word <= 0xebbf)) {\r
84 return QR_MODE_KANJI;\r
85 }\r
86 }\r
87 }\r
88\r
89 return QR_MODE_8;\r
90 } \r
91 \r
92 //----------------------------------------------------------------------\r
93 public function eatNum()\r
94 {\r
95 $ln = QRspec::lengthIndicator(QR_MODE_NUM, $this->input->getVersion());\r
96\r
97 $p = 0;\r
98 while(self::isdigitat($this->dataStr, $p)) {\r
99 $p++;\r
100 }\r
101 \r
102 $run = $p;\r
103 $mode = $this->identifyMode($p);\r
104 \r
105 if($mode == QR_MODE_8) {\r
106 $dif = QRinput::estimateBitsModeNum($run) + 4 + $ln\r
107 + QRinput::estimateBitsMode8(1) // + 4 + l8\r
108 - QRinput::estimateBitsMode8($run + 1); // - 4 - l8\r
109 if($dif > 0) {\r
110 return $this->eat8();\r
111 }\r
112 }\r
113 if($mode == QR_MODE_AN) {\r
114 $dif = QRinput::estimateBitsModeNum($run) + 4 + $ln\r
115 + QRinput::estimateBitsModeAn(1) // + 4 + la\r
116 - QRinput::estimateBitsModeAn($run + 1);// - 4 - la\r
117 if($dif > 0) {\r
118 return $this->eatAn();\r
119 }\r
120 }\r
121 \r
122 $ret = $this->input->append(QR_MODE_NUM, $run, str_split($this->dataStr));\r
123 if($ret < 0)\r
124 return -1;\r
125\r
126 return $run;\r
127 }\r
128 \r
129 //----------------------------------------------------------------------\r
130 public function eatAn()\r
131 {\r
132 $la = QRspec::lengthIndicator(QR_MODE_AN, $this->input->getVersion());\r
133 $ln = QRspec::lengthIndicator(QR_MODE_NUM, $this->input->getVersion());\r
134\r
135 $p = 0;\r
136 \r
137 while(self::isalnumat($this->dataStr, $p)) {\r
138 if(self::isdigitat($this->dataStr, $p)) {\r
139 $q = $p;\r
140 while(self::isdigitat($this->dataStr, $q)) {\r
141 $q++;\r
142 }\r
143 \r
144 $dif = QRinput::estimateBitsModeAn($p) // + 4 + la\r
145 + QRinput::estimateBitsModeNum($q - $p) + 4 + $ln\r
146 - QRinput::estimateBitsModeAn($q); // - 4 - la\r
147 \r
148 if($dif < 0) {\r
149 break;\r
150 } else {\r
151 $p = $q;\r
152 }\r
153 } else {\r
154 $p++;\r
155 }\r
156 }\r
157\r
158 $run = $p;\r
159\r
160 if(!self::isalnumat($this->dataStr, $p)) {\r
161 $dif = QRinput::estimateBitsModeAn($run) + 4 + $la\r
162 + QRinput::estimateBitsMode8(1) // + 4 + l8\r
163 - QRinput::estimateBitsMode8($run + 1); // - 4 - l8\r
164 if($dif > 0) {\r
165 return $this->eat8();\r
166 }\r
167 }\r
168\r
169 $ret = $this->input->append(QR_MODE_AN, $run, str_split($this->dataStr));\r
170 if($ret < 0)\r
171 return -1;\r
172\r
173 return $run;\r
174 }\r
175 \r
176 //----------------------------------------------------------------------\r
177 public function eatKanji()\r
178 {\r
179 $p = 0;\r
180 \r
181 while($this->identifyMode($p) == QR_MODE_KANJI) {\r
182 $p += 2;\r
183 }\r
184 \r
185 $ret = $this->input->append(QR_MODE_KANJI, $p, str_split($this->dataStr));\r
186 if($ret < 0)\r
187 return -1;\r
188\r
6f7798b6 189 return $ret;\r
fb70f26e
AD
190 }\r
191\r
192 //----------------------------------------------------------------------\r
193 public function eat8()\r
194 {\r
195 $la = QRspec::lengthIndicator(QR_MODE_AN, $this->input->getVersion());\r
196 $ln = QRspec::lengthIndicator(QR_MODE_NUM, $this->input->getVersion());\r
197\r
198 $p = 1;\r
199 $dataStrLen = strlen($this->dataStr);\r
200 \r
201 while($p < $dataStrLen) {\r
202 \r
203 $mode = $this->identifyMode($p);\r
204 if($mode == QR_MODE_KANJI) {\r
205 break;\r
206 }\r
207 if($mode == QR_MODE_NUM) {\r
208 $q = $p;\r
209 while(self::isdigitat($this->dataStr, $q)) {\r
210 $q++;\r
211 }\r
212 $dif = QRinput::estimateBitsMode8($p) // + 4 + l8\r
213 + QRinput::estimateBitsModeNum($q - $p) + 4 + $ln\r
214 - QRinput::estimateBitsMode8($q); // - 4 - l8\r
215 if($dif < 0) {\r
216 break;\r
217 } else {\r
218 $p = $q;\r
219 }\r
220 } else if($mode == QR_MODE_AN) {\r
221 $q = $p;\r
222 while(self::isalnumat($this->dataStr, $q)) {\r
223 $q++;\r
224 }\r
225 $dif = QRinput::estimateBitsMode8($p) // + 4 + l8\r
226 + QRinput::estimateBitsModeAn($q - $p) + 4 + $la\r
227 - QRinput::estimateBitsMode8($q); // - 4 - l8\r
228 if($dif < 0) {\r
229 break;\r
230 } else {\r
231 $p = $q;\r
232 }\r
233 } else {\r
234 $p++;\r
235 }\r
236 }\r
237\r
238 $run = $p;\r
239 $ret = $this->input->append(QR_MODE_8, $run, str_split($this->dataStr));\r
240 \r
241 if($ret < 0)\r
242 return -1;\r
243\r
244 return $run;\r
245 }\r
246\r
247 //----------------------------------------------------------------------\r
248 public function splitString()\r
249 {\r
250 while (strlen($this->dataStr) > 0)\r
251 {\r
252 if($this->dataStr == '')\r
253 return 0;\r
254\r
255 $mode = $this->identifyMode(0);\r
256 \r
257 switch ($mode) {\r
258 case QR_MODE_NUM: $length = $this->eatNum(); break;\r
259 case QR_MODE_AN: $length = $this->eatAn(); break;\r
260 case QR_MODE_KANJI:\r
6f7798b6 261 if ($this->modeHint == QR_MODE_KANJI)\r
fb70f26e
AD
262 $length = $this->eatKanji();\r
263 else $length = $this->eat8();\r
264 break;\r
265 default: $length = $this->eat8(); break;\r
266 \r
267 }\r
268\r
269 if($length == 0) return 0;\r
270 if($length < 0) return -1;\r
271 \r
272 $this->dataStr = substr($this->dataStr, $length);\r
273 }\r
274 }\r
275\r
276 //----------------------------------------------------------------------\r
277 public function toUpper()\r
278 {\r
279 $stringLen = strlen($this->dataStr);\r
280 $p = 0;\r
281 \r
282 while ($p<$stringLen) {\r
6f7798b6 283 $mode = self::identifyMode(substr($this->dataStr, $p));\r
fb70f26e
AD
284 if($mode == QR_MODE_KANJI) {\r
285 $p += 2;\r
286 } else {\r
287 if (ord($this->dataStr[$p]) >= ord('a') && ord($this->dataStr[$p]) <= ord('z')) {\r
288 $this->dataStr[$p] = chr(ord($this->dataStr[$p]) - 32);\r
289 }\r
290 $p++;\r
291 }\r
292 }\r
293\r
294 return $this->dataStr;\r
295 }\r
296\r
297 //----------------------------------------------------------------------\r
298 public static function splitStringToQRinput($string, QRinput $input, $modeHint, $casesensitive = true)\r
299 {\r
300 if(is_null($string) || $string == '\0' || $string == '') {\r
301 throw new Exception('empty string!!!');\r
302 }\r
303\r
304 $split = new QRsplit($string, $input, $modeHint);\r
305 \r
306 if(!$casesensitive)\r
307 $split->toUpper();\r
308 \r
309 return $split->splitString();\r
310 }\r
6f7798b6 311 }