source-class-Com.Tecnick.Barcode.Type.Square.PdfFourOneSeven

It appears that you are using AdBlocking software. The cost of running this website is covered by advertisements. If you like it please feel free to a small amount of money to secure the future of this website.
Overview

Classes

Exceptions

  1: <?php
  2: /**
  3:  * PdfFourOneSeven.php
  4:  *
  5:  * @since       2015-02-21
  6:  * @category    Library
  7:  * @package     Barcode
  8:  * @author      Nicola Asuni <info@tecnick.com>
  9:  * @copyright   2015-2016 Nicola Asuni - Tecnick.com LTD
 10:  * @license     http://www.gnu.org/copyleft/lesser.html GNU-LGPL v3 (see LICENSE.TXT)
 11:  * @link        https://github.com/tecnickcom/tc-lib-barcode
 12:  *
 13:  * This file is part of tc-lib-barcode software library.
 14:  */
 15: 
 16: namespace Com\Tecnick\Barcode\Type\Square;
 17: 
 18: use \Com\Tecnick\Barcode\Exception as BarcodeException;
 19: use \Com\Tecnick\Barcode\Type\Square\PdfFourOneSeven\Data;
 20: 
 21: /**
 22:  * Com\Tecnick\Barcode\Type\Square\PdfFourOneSeven
 23:  *
 24:  * PdfFourOneSeven Barcode type class
 25:  * PDF417 (ISO/IEC 15438:2006)
 26:  *
 27:  * PDF417 (ISO/IEC 15438:2006) is a 2-dimensional stacked bar code created by Symbol Technologies in 1991.
 28:  * It is one of the most popular 2D codes because of its ability to be read with slightly modified handheld
 29:  * laser or linear CCD scanners.
 30:  * TECHNICAL DATA / FEATURES OF PDF417:
 31:  *     Encodable Character Set:     All 128 ASCII Characters (including extended)
 32:  *     Code Type:                   Continuous, Multi-Row
 33:  *     Symbol Height:               3 - 90 Rows
 34:  *     Symbol Width:                90X - 583X
 35:  *     Bidirectional Decoding:      Yes
 36:  *     Error Correction Characters: 2 - 512
 37:  *     Maximum Data Characters:     1850 text, 2710 digits, 1108 bytes
 38:  *
 39:  * @since       2015-02-21
 40:  * @category    Library
 41:  * @package     Barcode
 42:  * @author      Nicola Asuni <info@tecnick.com>
 43:  * @copyright   2015-2016 Nicola Asuni - Tecnick.com LTD
 44:  * @license     http://www.gnu.org/copyleft/lesser.html GNU-LGPL v3 (see LICENSE.TXT)
 45:  * @link        https://github.com/tecnickcom/tc-lib-barcode
 46:  */
 47: class PdfFourOneSeven extends \Com\Tecnick\Barcode\Type\Square\PdfFourOneSeven\Compaction
 48: {
 49:     /**
 50:      * Barcode format
 51:      *
 52:      * @var string
 53:      */
 54:     protected $format = 'PDF417';
 55: 
 56:     /**
 57:      * Row height respect X dimension of single module
 58:      *
 59:      * @var int
 60:      */
 61:     protected $row_height = 2;
 62: 
 63:     /**
 64:      * Horizontal quiet zone in modules
 65:      *
 66:      * @var int
 67:      */
 68:     protected $quiet_vertical = 2;
 69: 
 70:     /**
 71:      * Vertical quiet zone in modules
 72:      *
 73:      * @var int
 74:      */
 75:     protected $quiet_horizontal = 2;
 76: 
 77:     /**
 78:      * Aspect ratio (width / height)
 79:      *
 80:      * @var int
 81:      */
 82:     protected $aspectratio = 2;
 83: 
 84:     /**
 85:      * Error correction level (0-8);
 86:      * Default -1 = automatic correction level
 87:      *
 88:      * @var int
 89:      */
 90:     protected $ecl = -1;
 91:     
 92:     /**
 93:      * Information for macro block
 94:      *
 95:      * @var int
 96:      */
 97:     protected $macro = array();
 98: 
 99:     /**
100:      * Set extra (optional) parameters
101:      */
102:     protected function setParameters()
103:     {
104:         parent::setParameters();
105:         // aspect ratio
106:         if (!empty($this->params[0]) && (($aspectratio = floatval($this->params[0])) >= 1)) {
107:             $this->aspectratio = $aspectratio;
108:         }
109:         // error correction level (auto)
110:         if (isset($this->params[1]) && (($ecl = intval($this->params[1])) >= 0) && ($ecl <= 8)) {
111:             $this->ecl = $ecl;
112:         }
113:         // macro block
114:         $this->setMacroBlockParam();
115:     }
116: 
117:     /**
118:      * Set macro block parameter
119:      */
120:     protected function setMacroBlockParam()
121:     {
122:         if (isset($this->params[4])
123:             && ($this->params[2] !== '')
124:             && ($this->params[3] !== '')
125:             && ($this->params[4] !== '')
126:         ) {
127:             $this->macro['segment_total'] = intval($this->params[2]);
128:             $this->macro['segment_index'] = intval($this->params[3]);
129:             $this->macro['file_id'] = strtr($this->params[4], "\xff", ',');
130:             for ($idx = 0; $idx < 7; ++$idx) {
131:                 $opt = $idx + 5;
132:                 if (isset($this->params[$opt]) && ($this->params[$opt] !== '')) {
133:                     $this->macro['option_'.$idx] = strtr($this->params[$opt], "\xff", ',');
134:                 }
135:             }
136:         }
137:     }
138: 
139:     /**
140:      * Get the bars array
141:      *
142:      * @throws BarcodeException in case of error
143:      */
144:     protected function setBars()
145:     {
146:         if (strlen((string)$this->code) == 0) {
147:             throw new BarcodeException('Empty input');
148:         }
149:         $barcode = $this->getBinSequence();
150:         $this->processBinarySequence($barcode);
151:     }
152: 
153:     /**
154:      * Get macro control block codewords
155:      *
156:      * @param int $numcw Number of codewords
157:      *
158:      * @return array
159:      */
160:     protected function getMacroBlock(&$numcw)
161:     {
162:         if (empty($this->macro)) {
163:             return array();
164:         }
165:         $macrocw = array();
166:         // beginning of macro control block
167:         $macrocw[] = 928;
168:         // segment index
169:         $cdw = $this->getCompaction(902, sprintf('%05d', $this->macro['segment_index']), false);
170:         $macrocw = array_merge($macrocw, $cdw);
171:         // file ID
172:         $cdw = $this->getCompaction(900, $this->macro['file_id'], false);
173:         $macrocw = array_merge($macrocw, $cdw);
174:         // optional fields
175:         $optmodes = array(900,902,902,900,900,902,902);
176:         $optsize = array(-1,2,4,-1,-1,-1,2);
177:         foreach ($optmodes as $key => $omode) {
178:             if (isset($this->macro['option_'.$key])) {
179:                 $macrocw[] = 923;
180:                 $macrocw[] = $key;
181:                 if ($optsize[$key] == 2) {
182:                     $this->macro['option_'.$key] = sprintf('%05d', $this->macro['option_'.$key]);
183:                 } elseif ($optsize[$key] == 4) {
184:                     $this->macro['option_'.$key] = sprintf('%010d', $this->macro['option_'.$key]);
185:                 }
186:                 $cdw = $this->getCompaction($omode, $this->macro['option_'.$key], false);
187:                 $macrocw = array_merge($macrocw, $cdw);
188:             }
189:         }
190:         if ($this->macro['segment_index'] == ($this->macro['segment_total'] - 1)) {
191:             // end of control block
192:             $macrocw[] = 922;
193:         }
194:         // update total codewords
195:         $numcw += count($macrocw);
196:         return $macrocw;
197:     }
198: 
199:     /**
200:      * Get codewords
201:      *
202:      * @param int $rows number of rows
203:      * @param int $cols number of columns
204:      * @param int $ecl eroor correction level
205:      *
206:      * @return array
207:      *
208:      * @throws BarcodeException in case of error
209:      */
210:     public function getCodewords(&$rows, &$cols, &$ecl)
211:     {
212:         $codewords = array(); // array of code-words
213:         // get the input sequence array
214:         $sequence = $this->getInputSequences($this->code);
215:         foreach ($sequence as $seq) {
216:             $cw = $this->getCompaction($seq[0], $seq[1], true);
217:             $codewords = array_merge($codewords, $cw);
218:         }
219:         if ($codewords[0] == 900) {
220:             // Text Alpha is the default mode, so remove the first code
221:             array_shift($codewords);
222:         }
223:         // count number of codewords
224:         $numcw = count($codewords);
225:         if ($numcw > 925) {
226:             throw new BarcodeException('The maximum codeword capaciy has been reached: '.$numcw.' > 925');
227:         }
228:         $macrocw = $this->getMacroBlock($numcw);
229:         // set error correction level
230:         $ecl = $this->getErrorCorrectionLevel($this->ecl, $numcw);
231:         // number of codewords for error correction
232:         $errsize = (2 << $ecl);
233:         // calculate number of columns (number of codewords per row) and rows
234:         $nce = ($numcw + $errsize + 1);
235:         $cols = min(30, max(1, round((sqrt(4761 + (68 * $this->aspectratio * $this->row_height * $nce)) - 69) / 34)));
236:         $rows = min(90, max(3, ceil($nce / $cols)));
237:         $size = ($cols * $rows);
238:         if ($size > 928) {
239:             // set dimensions to get maximum capacity
240:             if (abs($this->aspectratio - (17 * 29 / 32)) < abs($this->aspectratio - (17 * 16 / 58))) {
241:                 $cols = 29;
242:                 $rows = 32;
243:             } else {
244:                 $cols = 16;
245:                 $rows = 58;
246:             }
247:             $size = 928;
248:         }
249:         // calculate padding
250:         $pad = ($size - $nce);
251:         if ($pad > 0) {
252:             // add padding
253:             $codewords = array_merge($codewords, array_fill(0, $pad, 900));
254:         }
255:         if (!empty($macrocw)) {
256:             // add macro section
257:             $codewords = array_merge($codewords, $macrocw);
258:         }
259:         // Symbol Length Descriptor (number of data codewords including Symbol Length Descriptor and pad codewords)
260:         $sld = ($size - $errsize);
261:         // add symbol length description
262:         array_unshift($codewords, $sld);
263:         // calculate error correction
264:         $ecw = $this->getErrorCorrection($codewords, $ecl);
265:         // add error correction codewords
266:         return array_merge($codewords, $ecw);
267:     }
268: 
269:     /**
270:      * Creates a PDF417 object as binary string
271:      *
272:      * @return array barcode as binary string
273:      *
274:      * @throws BarcodeException in case of error
275:      */
276:     public function getBinSequence()
277:     {
278:         $rows = 0;
279:         $cols = 0;
280:         $ecl = 0;
281:         $codewords = $this->getCodewords($rows, $cols, $ecl);
282:         $barcode = '';
283:         // add horizontal quiet zones to start and stop patterns
284:         $pstart = str_repeat('0', $this->quiet_horizontal).Data::$start_pattern;
285:         $this->nrows = ($rows * $this->row_height) + (2 * $this->quiet_vertical);
286:         $this->ncols = (($cols + 2) * 17) + 35 + (2 * $this->quiet_horizontal);
287:         // build rows for vertical quiet zone
288:         $empty_row = ','.str_repeat('0', $this->ncols);
289:         $empty_rows = str_repeat($empty_row, $this->quiet_vertical);
290:         $barcode .= $empty_rows;
291:         $kcw = 0; // codeword index
292:         $cid = 0; // initial cluster
293:         // for each row
294:         for ($rix = 0; $rix < $rows; ++$rix) {
295:             // row start code
296:             $row = $pstart;
297:             switch ($cid) {
298:                 case 0:
299:                     $rval = ((30 * intval($rix / 3)) + intval(($rows - 1) / 3));
300:                     $cval = ((30 * intval($rix / 3)) + ($cols - 1));
301:                     break;
302:                 case 1:
303:                     $rval = ((30 * intval($rix / 3)) + ($ecl * 3) + (($rows - 1) % 3));
304:                     $cval = ((30 * intval($rix / 3)) + intval(($rows - 1) / 3));
305:                     break;
306:                 case 2:
307:                     $rval = ((30 * intval($rix / 3)) + ($cols - 1));
308:                     $cval = ((30 * intval($rix / 3)) + ($ecl * 3) + (($rows - 1) % 3));
309:                     break;
310:             }
311:             // left row indicator
312:             $row .= sprintf('%17b', Data::$clusters[$cid][$rval]);
313:             // for each column
314:             for ($cix = 0; $cix < $cols; ++$cix) {
315:                 $row .= sprintf('%17b', Data::$clusters[$cid][$codewords[$kcw]]);
316:                 ++$kcw;
317:             }
318:             // right row indicator
319:             $row .= sprintf('%17b', Data::$clusters[$cid][$cval]);
320:             // row stop code
321:             $row .= Data::$stop_pattern.str_repeat('0', $this->quiet_horizontal);
322:             $brow = ','.str_repeat($row, $this->row_height);
323:             $barcode .= $brow;
324:             ++$cid;
325:             if ($cid > 2) {
326:                 $cid = 0;
327:             }
328:         }
329:         $barcode .= $empty_rows;
330:         return $barcode;
331:     }
332: }
333: 
 

© 2004-2018 – Nicola Asuni - Tecnick.com - All rights reserved.
about - disclaimer - privacy