]>
git.immae.eu Git - github/wallabag/wallabag.git/blob - inc/3rdparty/libraries/tcpdf/include/barcodes/datamatrix.php
2 //============================================================+
3 // File name : datamatrix.php
6 // Last Update : 2014-05-06
7 // Author : Nicola Asuni - Tecnick.com LTD - www.tecnick.com - info@tecnick.com
8 // License : GNU-LGPL v3 (http://www.gnu.org/copyleft/lesser.html)
9 // -------------------------------------------------------------------
10 // Copyright (C) 2010-2014 Nicola Asuni - Tecnick.com LTD
12 // This file is part of TCPDF software library.
14 // TCPDF is free software: you can redistribute it and/or modify it
15 // under the terms of the GNU Lesser General Public License as
16 // published by the Free Software Foundation, either version 3 of the
17 // License, or (at your option) any later version.
19 // TCPDF is distributed in the hope that it will be useful, but
20 // WITHOUT ANY WARRANTY; without even the implied warranty of
21 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
22 // See the GNU Lesser General Public License for more details.
24 // You should have received a copy of the GNU Lesser General Public License
25 // along with TCPDF. If not, see <http://www.gnu.org/licenses/>.
27 // See LICENSE.TXT file for more information.
28 // -------------------------------------------------------------------
32 // Class to create DataMatrix ECC 200 barcode arrays for TCPDF class.
33 // DataMatrix (ISO/IEC 16022:2006) is a 2-dimensional bar code.
34 //============================================================+
38 * Class to create DataMatrix ECC 200 barcode arrays for TCPDF class.
39 * DataMatrix (ISO/IEC 16022:2006) is a 2-dimensional bar code.
41 * @package com.tecnick.tcpdf
42 * @author Nicola Asuni
47 if (! defined ( 'DATAMATRIXDEFS' )) {
50 * Indicate that definitions for this class are set
52 define ( 'DATAMATRIXDEFS' , true );
54 // -----------------------------------------------------
56 } // end of custom definitions
58 // #*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#
62 * ASCII encoding: ASCII character 0 to 127 (1 byte per CW)
64 define ( 'ENC_ASCII' , 0 );
67 * C40 encoding: Upper-case alphanumeric (3/2 bytes per CW)
72 * TEXT encoding: Lower-case alphanumeric (3/2 bytes per CW)
77 * X12 encoding: ANSI X12 (3/2 byte per CW)
82 * EDIFACT encoding: ASCII character 32 to 94 (4/3 bytes per CW)
87 * BASE 256 encoding: ASCII character 0 to 255 (1 byte per CW)
89 define ( 'ENC_BASE256' , 5 );
92 * ASCII extended encoding: ASCII character 128 to 255 (1/2 byte per CW)
94 define ( 'ENC_ASCII_EXT' , 6 );
97 * ASCII number encoding: ASCII digits (2 bytes per CW)
99 define ( 'ENC_ASCII_NUM' , 7 );
103 * Class to create DataMatrix ECC 200 barcode arrays for TCPDF class.
104 * DataMatrix (ISO/IEC 16022:2006) is a 2-dimensional bar code.
106 * @package com.tecnick.tcpdf
107 * @author Nicola Asuni
113 * Barcode array to be returned which is readable by TCPDF.
116 protected $barcode_array = array ();
119 * Store last used encoding for data codewords.
122 protected $last_enc = ENC_ASCII
;
125 * Table of Data Matrix ECC 200 Symbol Attributes:<ul>
126 * <li>total matrix rows (including finder pattern)</li>
127 * <li>total matrix cols (including finder pattern)</li>
128 * <li>total matrix rows (without finder pattern)</li>
129 * <li>total matrix cols (without finder pattern)</li>
130 * <li>region data rows (with finder pattern)</li>
131 * <li>region data col (with finder pattern)</li>
132 * <li>region data rows (without finder pattern)</li>
133 * <li>region data col (without finder pattern)</li>
134 * <li>horizontal regions</li>
135 * <li>vertical regions</li>
137 * <li>data codewords</li>
138 * <li>error codewords</li>
140 * <li>data codewords per block</li>
141 * <li>error codewords per block</li>
145 protected $symbattr = array (
146 // square form ---------------------------------------------------------------------------------------
147 array ( 0x00a , 0x00a , 0x008 , 0x008 , 0x00a , 0x00a , 0x008 , 0x008 , 0x001 , 0x001 , 0x001 , 0x003 , 0x005 , 0x001 , 0x003 , 0x005 ), // 10x10
148 array ( 0x00c , 0x00c , 0x00a , 0x00a , 0x00c , 0x00c , 0x00a , 0x00a , 0x001 , 0x001 , 0x001 , 0x005 , 0x007 , 0x001 , 0x005 , 0x007 ), // 12x12
149 array ( 0x00e , 0x00e , 0x00c , 0x00c , 0x00e , 0x00e , 0x00c , 0x00c , 0x001 , 0x001 , 0x001 , 0x008 , 0x00a , 0x001 , 0x008 , 0x00a ), // 14x14
150 array ( 0x010 , 0x010 , 0x00e , 0x00e , 0x010 , 0x010 , 0x00e , 0x00e , 0x001 , 0x001 , 0x001 , 0x00c , 0x00c , 0x001 , 0x00c , 0x00c ), // 16x16
151 array ( 0x012 , 0x012 , 0x010 , 0x010 , 0x012 , 0x012 , 0x010 , 0x010 , 0x001 , 0x001 , 0x001 , 0x012 , 0x00e , 0x001 , 0x012 , 0x00e ), // 18x18
152 array ( 0x014 , 0x014 , 0x012 , 0x012 , 0x014 , 0x014 , 0x012 , 0x012 , 0x001 , 0x001 , 0x001 , 0x016 , 0x012 , 0x001 , 0x016 , 0x012 ), // 20x20
153 array ( 0x016 , 0x016 , 0x014 , 0x014 , 0x016 , 0x016 , 0x014 , 0x014 , 0x001 , 0x001 , 0x001 , 0x01e , 0x014 , 0x001 , 0x01e , 0x014 ), // 22x22
154 array ( 0x018 , 0x018 , 0x016 , 0x016 , 0x018 , 0x018 , 0x016 , 0x016 , 0x001 , 0x001 , 0x001 , 0x024 , 0x018 , 0x001 , 0x024 , 0x018 ), // 24x24
155 array ( 0x01a , 0x01a , 0x018 , 0x018 , 0x01a , 0x01a , 0x018 , 0x018 , 0x001 , 0x001 , 0x001 , 0x02c , 0x01c , 0x001 , 0x02c , 0x01c ), // 26x26
156 array ( 0x020 , 0x020 , 0x01c , 0x01c , 0x010 , 0x010 , 0x00e , 0x00e , 0x002 , 0x002 , 0x004 , 0x03e , 0x024 , 0x001 , 0x03e , 0x024 ), // 32x32
157 array ( 0x024 , 0x024 , 0x020 , 0x020 , 0x012 , 0x012 , 0x010 , 0x010 , 0x002 , 0x002 , 0x004 , 0x056 , 0x02a , 0x001 , 0x056 , 0x02a ), // 36x36
158 array ( 0x028 , 0x028 , 0x024 , 0x024 , 0x014 , 0x014 , 0x012 , 0x012 , 0x002 , 0x002 , 0x004 , 0x072 , 0x030 , 0x001 , 0x072 , 0x030 ), // 40x40
159 array ( 0x02c , 0x02c , 0x028 , 0x028 , 0x016 , 0x016 , 0x014 , 0x014 , 0x002 , 0x002 , 0x004 , 0x090 , 0x038 , 0x001 , 0x090 , 0x038 ), // 44x44
160 array ( 0x030 , 0x030 , 0x02c , 0x02c , 0x018 , 0x018 , 0x016 , 0x016 , 0x002 , 0x002 , 0x004 , 0x0ae , 0x044 , 0x001 , 0x0ae , 0x044 ), // 48x48
161 array ( 0x034 , 0x034 , 0x030 , 0x030 , 0x01a , 0x01a , 0x018 , 0x018 , 0x002 , 0x002 , 0x004 , 0x0cc , 0x054 , 0x002 , 0x066 , 0x02a ), // 52x52
162 array ( 0x040 , 0x040 , 0x038 , 0x038 , 0x010 , 0x010 , 0x00e , 0x00e , 0x004 , 0x004 , 0x010 , 0x118 , 0x070 , 0x002 , 0x08c , 0x038 ), // 64x64
163 array ( 0x048 , 0x048 , 0x040 , 0x040 , 0x012 , 0x012 , 0x010 , 0x010 , 0x004 , 0x004 , 0x010 , 0x170 , 0x090 , 0x004 , 0x05c , 0x024 ), // 72x72
164 array ( 0x050 , 0x050 , 0x048 , 0x048 , 0x014 , 0x014 , 0x012 , 0x012 , 0x004 , 0x004 , 0x010 , 0x1c8 , 0x0c0 , 0x004 , 0x072 , 0x030 ), // 80x80
165 array ( 0x058 , 0x058 , 0x050 , 0x050 , 0x016 , 0x016 , 0x014 , 0x014 , 0x004 , 0x004 , 0x010 , 0x240 , 0x0e0 , 0x004 , 0x090 , 0x038 ), // 88x88
166 array ( 0x060 , 0x060 , 0x058 , 0x058 , 0x018 , 0x018 , 0x016 , 0x016 , 0x004 , 0x004 , 0x010 , 0x2b8 , 0x110 , 0x004 , 0x0ae , 0x044 ), // 96x96
167 array ( 0x068 , 0x068 , 0x060 , 0x060 , 0x01a , 0x01a , 0x018 , 0x018 , 0x004 , 0x004 , 0x010 , 0x330 , 0x150 , 0x006 , 0x088 , 0x038 ), // 104x104
168 array ( 0x078 , 0x078 , 0x06c , 0x06c , 0x014 , 0x014 , 0x012 , 0x012 , 0x006 , 0x006 , 0x024 , 0x41a , 0x198 , 0x006 , 0x0af , 0x044 ), // 120x120
169 array ( 0x084 , 0x084 , 0x078 , 0x078 , 0x016 , 0x016 , 0x014 , 0x014 , 0x006 , 0x006 , 0x024 , 0x518 , 0x1f0 , 0x008 , 0x0a3 , 0x03e ), // 132x132
170 array ( 0x090 , 0x090 , 0x084 , 0x084 , 0x018 , 0x018 , 0x016 , 0x016 , 0x006 , 0x006 , 0x024 , 0x616 , 0x26c , 0x00a , 0x09c , 0x03e ), // 144x144
171 // rectangular form (currently unused) ---------------------------------------------------------------------------
172 array ( 0x008 , 0x012 , 0x006 , 0x010 , 0x008 , 0x012 , 0x006 , 0x010 , 0x001 , 0x001 , 0x001 , 0x005 , 0x007 , 0x001 , 0x005 , 0x007 ), // 8x18
173 array ( 0x008 , 0x020 , 0x006 , 0x01c , 0x008 , 0x010 , 0x006 , 0x00e , 0x001 , 0x002 , 0x002 , 0x00a , 0x00b , 0x001 , 0x00a , 0x00b ), // 8x32
174 array ( 0x00c , 0x01a , 0x00a , 0x018 , 0x00c , 0x01a , 0x00a , 0x018 , 0x001 , 0x001 , 0x001 , 0x010 , 0x00e , 0x001 , 0x010 , 0x00e ), // 12x26
175 array ( 0x00c , 0x024 , 0x00a , 0x020 , 0x00c , 0x012 , 0x00a , 0x010 , 0x001 , 0x002 , 0x002 , 0x00c , 0x012 , 0x001 , 0x00c , 0x012 ), // 12x36
176 array ( 0x010 , 0x024 , 0x00e , 0x020 , 0x010 , 0x012 , 0x00e , 0x010 , 0x001 , 0x002 , 0x002 , 0x020 , 0x018 , 0x001 , 0x020 , 0x018 ), // 16x36
177 array ( 0x010 , 0x030 , 0x00e , 0x02c , 0x010 , 0x018 , 0x00e , 0x016 , 0x001 , 0x002 , 0x002 , 0x031 , 0x01c , 0x001 , 0x031 , 0x01c ) // 16x48
181 * Map encodation modes whit character sets.
184 protected $chset_id = array ( ENC_C40
=> 'C40' , ENC_TXT
=> 'TXT' , ENC_X12
=> 'X12' );
187 * Basic set of characters for each encodation mode.
190 protected $chset = array (
191 'C40' => array ( // Basic set for C40 ----------------------------------------------------------------------------
192 'S1' => 0x00 , 'S2' => 0x01 , 'S3' => 0x02 , 0x20 => 0x03 , 0x30 => 0x04 , 0x31 => 0x05 , 0x32 => 0x06 , 0x33 => 0x07 , 0x34 => 0x08 , 0x35 => 0x09 , //
193 0x36 => 0x0a , 0x37 => 0x0b , 0x38 => 0x0c , 0x39 => 0x0d , 0x41 => 0x0e , 0x42 => 0x0f , 0x43 => 0x10 , 0x44 => 0x11 , 0x45 => 0x12 , 0x46 => 0x13 , //
194 0x47 => 0x14 , 0x48 => 0x15 , 0x49 => 0x16 , 0x4a => 0x17 , 0x4b => 0x18 , 0x4c => 0x19 , 0x4d => 0x1a , 0x4e => 0x1b , 0x4f => 0x1c , 0x50 => 0x1d , //
195 0x51 => 0x1e , 0x52 => 0x1f , 0x53 => 0x20 , 0x54 => 0x21 , 0x55 => 0x22 , 0x56 => 0x23 , 0x57 => 0x24 , 0x58 => 0x25 , 0x59 => 0x26 , 0x5a => 0x27 ), //
196 'TXT' => array ( // Basic set for TEXT ---------------------------------------------------------------------------
197 'S1' => 0x00 , 'S2' => 0x01 , 'S3' => 0x02 , 0x20 => 0x03 , 0x30 => 0x04 , 0x31 => 0x05 , 0x32 => 0x06 , 0x33 => 0x07 , 0x34 => 0x08 , 0x35 => 0x09 , //
198 0x36 => 0x0a , 0x37 => 0x0b , 0x38 => 0x0c , 0x39 => 0x0d , 0x61 => 0x0e , 0x62 => 0x0f , 0x63 => 0x10 , 0x64 => 0x11 , 0x65 => 0x12 , 0x66 => 0x13 , //
199 0x67 => 0x14 , 0x68 => 0x15 , 0x69 => 0x16 , 0x6a => 0x17 , 0x6b => 0x18 , 0x6c => 0x19 , 0x6d => 0x1a , 0x6e => 0x1b , 0x6f => 0x1c , 0x70 => 0x1d , //
200 0x71 => 0x1e , 0x72 => 0x1f , 0x73 => 0x20 , 0x74 => 0x21 , 0x75 => 0x22 , 0x76 => 0x23 , 0x77 => 0x24 , 0x78 => 0x25 , 0x79 => 0x26 , 0x7a => 0x27 ), //
201 'SH1' => array ( // Shift 1 set ----------------------------------------------------------------------------------
202 0x00 => 0x00 , 0x01 => 0x01 , 0x02 => 0x02 , 0x03 => 0x03 , 0x04 => 0x04 , 0x05 => 0x05 , 0x06 => 0x06 , 0x07 => 0x07 , 0x08 => 0x08 , 0x09 => 0x09 , //
203 0x0a => 0x0a , 0x0b => 0x0b , 0x0c => 0x0c , 0x0d => 0x0d , 0x0e => 0x0e , 0x0f => 0x0f , 0x10 => 0x10 , 0x11 => 0x11 , 0x12 => 0x12 , 0x13 => 0x13 , //
204 0x14 => 0x14 , 0x15 => 0x15 , 0x16 => 0x16 , 0x17 => 0x17 , 0x18 => 0x18 , 0x19 => 0x19 , 0x1a => 0x1a , 0x1b => 0x1b , 0x1c => 0x1c , 0x1d => 0x1d , //
205 0x1e => 0x1e , 0x1f => 0x1f ), //
206 'SH2' => array ( // Shift 2 set ----------------------------------------------------------------------------------
207 0x21 => 0x00 , 0x22 => 0x01 , 0x23 => 0x02 , 0x24 => 0x03 , 0x25 => 0x04 , 0x26 => 0x05 , 0x27 => 0x06 , 0x28 => 0x07 , 0x29 => 0x08 , 0x2a => 0x09 , //
208 0x2b => 0x0a , 0x2c => 0x0b , 0x2d => 0x0c , 0x2e => 0x0d , 0x2f => 0x0e , 0x3a => 0x0f , 0x3b => 0x10 , 0x3c => 0x11 , 0x3d => 0x12 , 0x3e => 0x13 , //
209 0x3f => 0x14 , 0x40 => 0x15 , 0x5b => 0x16 , 0x5c => 0x17 , 0x5d => 0x18 , 0x5e => 0x19 , 0x5f => 0x1a , 'F1' => 0x1b , 'US' => 0x1e ), //
210 'S3C' => array ( // Shift 3 set for C40 --------------------------------------------------------------------------
211 0x60 => 0x00 , 0x61 => 0x01 , 0x62 => 0x02 , 0x63 => 0x03 , 0x64 => 0x04 , 0x65 => 0x05 , 0x66 => 0x06 , 0x67 => 0x07 , 0x68 => 0x08 , 0x69 => 0x09 , //
212 0x6a => 0x0a , 0x6b => 0x0b , 0x6c => 0x0c , 0x6d => 0x0d , 0x6e => 0x0e , 0x6f => 0x0f , 0x70 => 0x10 , 0x71 => 0x11 , 0x72 => 0x12 , 0x73 => 0x13 , //
213 0x74 => 0x14 , 0x75 => 0x15 , 0x76 => 0x16 , 0x77 => 0x17 , 0x78 => 0x18 , 0x79 => 0x19 , 0x7a => 0x1a , 0x7b => 0x1b , 0x7c => 0x1c , 0x7d => 0x1d , //
214 0x7e => 0x1e , 0x7f => 0x1f ),
215 'S3T' => array ( // Shift 3 set for TEXT -------------------------------------------------------------------------
216 0x60 => 0x00 , 0x41 => 0x01 , 0x42 => 0x02 , 0x43 => 0x03 , 0x44 => 0x04 , 0x45 => 0x05 , 0x46 => 0x06 , 0x47 => 0x07 , 0x48 => 0x08 , 0x49 => 0x09 , //
217 0x4a => 0x0a , 0x4b => 0x0b , 0x4c => 0x0c , 0x4d => 0x0d , 0x4e => 0x0e , 0x4f => 0x0f , 0x50 => 0x10 , 0x51 => 0x11 , 0x52 => 0x12 , 0x53 => 0x13 , //
218 0x54 => 0x14 , 0x55 => 0x15 , 0x56 => 0x16 , 0x57 => 0x17 , 0x58 => 0x18 , 0x59 => 0x19 , 0x5a => 0x1a , 0x7b => 0x1b , 0x7c => 0x1c , 0x7d => 0x1d , //
219 0x7e => 0x1e , 0x7f => 0x1f ), //
220 'X12' => array ( // Set for X12 ----------------------------------------------------------------------------------
221 0x0d => 0x00 , 0x2a => 0x01 , 0x3e => 0x02 , 0x20 => 0x03 , 0x30 => 0x04 , 0x31 => 0x05 , 0x32 => 0x06 , 0x33 => 0x07 , 0x34 => 0x08 , 0x35 => 0x09 , //
222 0x36 => 0x0a , 0x37 => 0x0b , 0x38 => 0x0c , 0x39 => 0x0d , 0x41 => 0x0e , 0x42 => 0x0f , 0x43 => 0x10 , 0x44 => 0x11 , 0x45 => 0x12 , 0x46 => 0x13 , //
223 0x47 => 0x14 , 0x48 => 0x15 , 0x49 => 0x16 , 0x4a => 0x17 , 0x4b => 0x18 , 0x4c => 0x19 , 0x4d => 0x1a , 0x4e => 0x1b , 0x4f => 0x1c , 0x50 => 0x1d , //
224 0x51 => 0x1e , 0x52 => 0x1f , 0x53 => 0x20 , 0x54 => 0x21 , 0x55 => 0x22 , 0x56 => 0x23 , 0x57 => 0x24 , 0x58 => 0x25 , 0x59 => 0x26 , 0x5a => 0x27 ) //
227 // -----------------------------------------------------------------------------
230 * This is the class constructor.
231 * Creates a datamatrix object
232 * @param $code (string) Code to represent using Datamatrix.
235 public function __construct ( $code ) {
236 $barcode_array = array ();
237 if (( is_null ( $code )) OR ( $code == '\0' ) OR ( $code == '' )) {
240 // get data codewords
241 $cw = $this- > getHighLevelEncoding ( $code );
242 // number of data codewords
248 // get minimum required matrix size.
249 foreach ( $this- > symbattr
as $params ) {
250 if ( $params [ 11 ] >= $nd ) {
254 if ( $params [ 11 ] < $nd ) {
257 } elseif ( $params [ 11 ] > $nd ) {
259 if ((( $params [ 11 ] - $nd ) > 1 ) AND ( $cw [( $nd - 1 )] != 254 )) {
260 if ( $this- > last_enc
== ENC_EDF
) {
261 // switch to ASCII encoding
264 } elseif (( $this- > last_enc
!= ENC_ASCII
) AND ( $this- > last_enc
!= ENC_BASE256
)) {
265 // switch to ASCII encoding
270 if ( $params [ 11 ] > $nd ) {
274 // add remaining pads
275 for ( $i = $nd ; $i < $params [ 11 ]; ++
$i ) {
276 $cw [] = $this- > get253StateCodeword ( 129 , $i );
280 // add error correction codewords
281 $cw = $this- > getErrorCorrection ( $cw , $params [ 13 ], $params [ 14 ], $params [ 15 ]);
282 // initialize empty arrays
283 $grid = array_fill ( 0 , ( $params [ 2 ] * $params [ 3 ]), 0 );
285 $places = $this- > getPlacementMap ( $params [ 2 ], $params [ 3 ]);
286 // fill the grid with data
289 // region data row max index
290 $rdri = ( $params [ 4 ] - 1 );
291 // region data column max index
292 $rdci = ( $params [ 5 ] - 1 );
293 // for each vertical region
294 for ( $vr = 0 ; $vr < $params [ 9 ]; ++
$vr ) {
295 // for each row on region
296 for ( $r = 0 ; $r < $params [ 4 ]; ++
$r ) {
298 $row = (( $vr * $params [ 4 ]) +
$r );
299 // for each horizontal region
300 for ( $hr = 0 ; $hr < $params [ 8 ]; ++
$hr ) {
301 // for each column on region
302 for ( $c = 0 ; $c < $params [ 5 ]; ++
$c ) {
304 $col = (( $hr * $params [ 5 ]) +
$c );
307 // top finder pattern
309 $grid [ $row ][ $col ] = 0 ;
311 $grid [ $row ][ $col ] = 1 ;
313 } elseif ( $r == $rdri ) {
314 // bottom finder pattern
315 $grid [ $row ][ $col ] = 1 ;
317 // left finder pattern
318 $grid [ $row ][ $col ] = 1 ;
319 } elseif ( $c == $rdci ) {
320 // right finder pattern
322 $grid [ $row ][ $col ] = 1 ;
324 $grid [ $row ][ $col ] = 0 ;
327 if ( $places [ $i ] < 2 ) {
328 $grid [ $row ][ $col ] = $places [ $i ];
331 $cw_id = ( floor ( $places [ $i ] / 10 ) - 1 );
333 $cw_bit = pow ( 2 , ( 8 - ( $places [ $i ] %
10 )));
334 $grid [ $row ][ $col ] = (( $cw [ $cw_id ] & $cw_bit ) == 0 ) ? 0 : 1 ;
342 $this- > barcode_array
[ 'num_rows' ] = $params [ 0 ];
343 $this- > barcode_array
[ 'num_cols' ] = $params [ 1 ];
344 $this- > barcode_array
[ 'bcode' ] = $grid ;
348 * Returns a barcode array which is readable by TCPDF
349 * @return array barcode array readable by TCPDF;
352 public function getBarcodeArray () {
353 return $this- > barcode_array
;
357 * Product of two numbers in a Power-of-Two Galois Field
358 * @param $a (int) first number to multiply.
359 * @param $b (int) second number to multiply.
360 * @param $log (array) Log table.
361 * @param $alog (array) Anti-Log table.
362 * @param $gf (array) Number of Factors of the Reed-Solomon polynomial.
363 * @return int product
366 protected function getGFProduct ( $a , $b , $log , $alog , $gf ) {
367 if (( $a == 0 ) OR ( $b == 0 )) {
370 return ( $alog [( $log [ $a ] +
$log [ $b ]) %
( $gf - 1 )]);
374 * Add error correction codewords to data codewords array (ANNEX E).
375 * @param $wd (array) Array of datacodewords.
376 * @param $nb (int) Number of blocks.
377 * @param $nd (int) Number of data codewords per block.
378 * @param $nc (int) Number of correction codewords per block.
379 * @param $gf (int) numner of fields on log/antilog table (power of 2).
380 * @param $pp (int) The value of its prime modulus polynomial (301 for ECC200).
381 * @return array data codewords + error codewords
384 protected function getErrorCorrection ( $wd , $nb , $nd , $nc , $gf = 256 , $pp = 301 ) {
385 // generate the log ($log) and antilog ($alog) tables
388 for ( $i = 1 ; $i < $gf ; ++
$i ) {
389 $alog [ $i ] = ( $alog [( $i - 1 )] * 2 );
390 if ( $alog [ $i ] >= $gf ) {
393 $log [ $alog [ $i ]] = $i ;
396 // generate the polynomial coefficients (c)
397 $c = array_fill ( 0 , ( $nc +
1 ), 0 );
399 for ( $i = 1 ; $i <= $nc ; ++
$i ) {
401 for ( $j = ( $i - 1 ); $j >= 1 ; -- $j ) {
402 $c [ $j ] = $c [( $j - 1 )] ^
$this- > getGFProduct ( $c [ $j ], $alog [ $i ], $log , $alog , $gf );
404 $c [ 0 ] = $this- > getGFProduct ( $c [ 0 ], $alog [ $i ], $log , $alog , $gf );
407 // total number of data codewords
408 $num_wd = ( $nb * $nd );
409 // total number of error codewords
410 $num_we = ( $nb * $nc );
412 for ( $b = 0 ; $b < $nb ; ++
$b ) {
413 // create interleaved data block
415 for ( $n = $b ; $n < $num_wd ; $n +
= $nb ) {
418 // initialize error codewords
419 $we = array_fill ( 0 , ( $nc +
1 ), 0 );
420 // calculate error correction codewords for this block
421 for ( $i = 0 ; $i < $nd ; ++
$i ) {
422 $k = ( $we [ 0 ] ^
$block [ $i ]);
423 for ( $j = 0 ; $j < $nc ; ++
$j ) {
424 $we [ $j ] = ( $we [( $j +
1 )] ^
$this- > getGFProduct ( $k , $c [( $nc - $j - 1 )], $log , $alog , $gf ));
427 // add error codewords at the end of data codewords
429 for ( $i = $b ; $i < $num_we ; $i +
= $nb ) {
430 $wd [( $num_wd +
$i )] = $we [ $j ];
440 * Return the 253-state codeword
441 * @param $cwpad (int) Pad codeword.
442 * @param $cwpos (int) Number of data codewords from the beginning of encoded data.
443 * @return pad codeword
446 protected function get253StateCodeword ( $cwpad , $cwpos ) {
447 $pad = ( $cwpad +
((( 149 * $cwpos ) %
253 ) +
1 ));
455 * Return the 255-state codeword
456 * @param $cwpad (int) Pad codeword.
457 * @param $cwpos (int) Number of data codewords from the beginning of encoded data.
458 * @return pad codeword
461 protected function get255StateCodeword ( $cwpad , $cwpos ) {
462 $pad = ( $cwpad +
((( 149 * $cwpos ) %
255 ) +
1 ));
470 * Returns true if the char belongs to the selected mode
471 * @param $chr (int) Character (byte) to check.
472 * @param $mode (int) Current encoding mode.
473 * @return boolean true if the char is of the selected mode.
476 protected function isCharMode ( $chr , $mode ) {
479 case ENC_ASCII
: { // ASCII character 0 to 127
480 $status = (( $chr >= 0 ) AND ( $chr <= 127 ));
483 case ENC_C40
: { // Upper-case alphanumeric
484 $status = (( $chr == 32 ) OR (( $chr >= 48 ) AND ( $chr <= 57 )) OR (( $chr >= 65 ) AND ( $chr <= 90 )));
487 case ENC_TXT
: { // Lower-case alphanumeric
488 $status = (( $chr == 32 ) OR (( $chr >= 48 ) AND ( $chr <= 57 )) OR (( $chr >= 97 ) AND ( $chr <= 122 )));
491 case ENC_X12
: { // ANSI X12
492 $status = (( $chr == 13 ) OR ( $chr == 42 ) OR ( $chr == 62 ));
495 case ENC_EDF
: { // ASCII character 32 to 94
496 $status = (( $chr >= 32 ) AND ( $chr <= 94 ));
499 case ENC_BASE256
: { // Function character (FNC1, Structured Append, Reader Program, or Code Page)
500 $status = (( $chr == 232 ) OR ( $chr == 233 ) OR ( $chr == 234 ) OR ( $chr == 241 ));
503 case ENC_ASCII_EXT
: { // ASCII character 128 to 255
504 $status = (( $chr >= 128 ) AND ( $chr <= 255 ));
507 case ENC_ASCII_NUM
: { // ASCII digits
508 $status = (( $chr >= 48 ) AND ( $chr <= 57 ));
516 * The look-ahead test scans the data to be encoded to find the best mode (Annex P - steps from J to S).
517 * @param $data (string) data to encode
518 * @param $pos (int) current position
519 * @param $mode (int) current encoding mode
520 * @return int encoding mode
523 protected function lookAheadTest ( $data , $pos , $mode ) {
524 $data_length = strlen ( $data );
525 if ( $pos >= $data_length ) {
528 $charscount = 0 ; // count processed chars
530 if ( $mode == ENC_ASCII
) {
531 $numch = array ( 0 , 1 , 1 , 1 , 1 , 1.25 );
533 $numch = array ( 1 , 2 , 2 , 2 , 2 , 2.25 );
538 if (( $pos +
$charscount ) == $data_length ) {
539 if ( $numch [ ENC_ASCII
] <= ceil ( min ( $numch [ ENC_C40
], $numch [ ENC_TXT
], $numch [ ENC_X12
], $numch [ ENC_EDF
], $numch [ ENC_BASE256
]))) {
542 if ( $numch [ ENC_BASE256
] < ceil ( min ( $numch [ ENC_ASCII
], $numch [ ENC_C40
], $numch [ ENC_TXT
], $numch [ ENC_X12
], $numch [ ENC_EDF
]))) {
545 if ( $numch [ ENC_EDF
] < ceil ( min ( $numch [ ENC_ASCII
], $numch [ ENC_C40
], $numch [ ENC_TXT
], $numch [ ENC_X12
], $numch [ ENC_BASE256
]))) {
548 if ( $numch [ ENC_TXT
] < ceil ( min ( $numch [ ENC_ASCII
], $numch [ ENC_C40
], $numch [ ENC_X12
], $numch [ ENC_EDF
], $numch [ ENC_BASE256
]))) {
551 if ( $numch [ ENC_X12
] < ceil ( min ( $numch [ ENC_ASCII
], $numch [ ENC_C40
], $numch [ ENC_TXT
], $numch [ ENC_EDF
], $numch [ ENC_BASE256
]))) {
557 $chr = ord ( $data [ $pos +
$charscount ]);
560 if ( $this- > isCharMode ( $chr , ENC_ASCII_NUM
)) {
561 $numch [ ENC_ASCII
] +
= ( 1 / 2 );
562 } elseif ( $this- > isCharMode ( $chr , ENC_ASCII_EXT
)) {
563 $numch [ ENC_ASCII
] = ceil ( $numch [ ENC_ASCII
]);
564 $numch [ ENC_ASCII
] +
= 2 ;
566 $numch [ ENC_ASCII
] = ceil ( $numch [ ENC_ASCII
]);
567 $numch [ ENC_ASCII
] +
= 1 ;
570 if ( $this- > isCharMode ( $chr , ENC_C40
)) {
571 $numch [ ENC_C40
] +
= ( 2 / 3 );
572 } elseif ( $this- > isCharMode ( $chr , ENC_ASCII_EXT
)) {
573 $numch [ ENC_C40
] +
= ( 8 / 3 );
575 $numch [ ENC_C40
] +
= ( 4 / 3 );
578 if ( $this- > isCharMode ( $chr , ENC_TXT
)) {
579 $numch [ ENC_TXT
] +
= ( 2 / 3 );
580 } elseif ( $this- > isCharMode ( $chr , ENC_ASCII_EXT
)) {
581 $numch [ ENC_TXT
] +
= ( 8 / 3 );
583 $numch [ ENC_TXT
] +
= ( 4 / 3 );
586 if ( $this- > isCharMode ( $chr , ENC_X12
) OR $this- > isCharMode ( $chr , ENC_C40
)) {
587 $numch [ ENC_X12
] +
= ( 2 / 3 );
588 } elseif ( $this- > isCharMode ( $chr , ENC_ASCII_EXT
)) {
589 $numch [ ENC_X12
] +
= ( 13 / 3 );
591 $numch [ ENC_X12
] +
= ( 10 / 3 );
594 if ( $this- > isCharMode ( $chr , ENC_EDF
)) {
595 $numch [ ENC_EDF
] +
= ( 3 / 4 );
596 } elseif ( $this- > isCharMode ( $chr , ENC_ASCII_EXT
)) {
597 $numch [ ENC_EDF
] +
= ( 17 / 4 );
599 $numch [ ENC_EDF
] +
= ( 13 / 4 );
602 if ( $this- > isCharMode ( $chr , ENC_BASE256
)) {
603 $numch [ ENC_BASE256
] +
= 4 ;
605 $numch [ ENC_BASE256
] +
= 1 ;
608 if ( $charscount >= 4 ) {
609 if (( $numch [ ENC_ASCII
] +
1 ) <= min ( $numch [ ENC_C40
], $numch [ ENC_TXT
], $numch [ ENC_X12
], $numch [ ENC_EDF
], $numch [ ENC_BASE256
])) {
612 if ((( $numch [ ENC_BASE256
] +
1 ) <= $numch [ ENC_ASCII
])
613 OR (( $numch [ ENC_BASE256
] +
1 ) < min ( $numch [ ENC_C40
], $numch [ ENC_TXT
], $numch [ ENC_X12
], $numch [ ENC_EDF
]))) {
616 if (( $numch [ ENC_EDF
] +
1 ) < min ( $numch [ ENC_ASCII
], $numch [ ENC_C40
], $numch [ ENC_TXT
], $numch [ ENC_X12
], $numch [ ENC_BASE256
])) {
619 if (( $numch [ ENC_TXT
] +
1 ) < min ( $numch [ ENC_ASCII
], $numch [ ENC_C40
], $numch [ ENC_X12
], $numch [ ENC_EDF
], $numch [ ENC_BASE256
])) {
622 if (( $numch [ ENC_X12
] +
1 ) < min ( $numch [ ENC_ASCII
], $numch [ ENC_C40
], $numch [ ENC_TXT
], $numch [ ENC_EDF
], $numch [ ENC_BASE256
])) {
625 if (( $numch [ ENC_C40
] +
1 ) < min ( $numch [ ENC_ASCII
], $numch [ ENC_TXT
], $numch [ ENC_EDF
], $numch [ ENC_BASE256
])) {
626 if ( $numch [ ENC_C40
] < $numch [ ENC_X12
]) {
629 if ( $numch [ ENC_C40
] == $numch [ ENC_X12
]) {
630 $k = ( $pos +
$charscount +
1 );
631 while ( $k < $data_length ) {
632 $tmpchr = ord ( $data{ $k
});
633 if ( $this- > isCharMode ( $tmpchr , ENC_X12
)) {
635 } elseif (!( $this- > isCharMode ( $tmpchr , ENC_X12
) OR $this- > isCharMode ( $tmpchr , ENC_C40
))) {
648 * Get the switching codeword to a new encoding mode (latch codeword)
649 * @param $mode (int) New encoding mode.
650 * @return (int) Switch codeword.
653 protected function getSwitchEncodingCodeword ( $mode ) {
655 case ENC_ASCII
: { // ASCII character 0 to 127
657 if ( $this- > last_enc
== ENC_EDF
) {
662 case ENC_C40
: { // Upper-case alphanumeric
666 case ENC_TXT
: { // Lower-case alphanumeric
670 case ENC_X12
: { // ANSI X12
674 case ENC_EDF
: { // ASCII character 32 to 94
678 case ENC_BASE256
: { // Function character (FNC1, Structured Append, Reader Program, or Code Page)
687 * Choose the minimum matrix size and return the max number of data codewords.
688 * @param $numcw (int) Number of current codewords.
689 * @return number of data codewords in matrix
692 protected function getMaxDataCodewords ( $numcw ) {
693 foreach ( $this- > symbattr
as $key => $matrix ) {
694 if ( $matrix [ 11 ] >= $numcw ) {
702 * Get high level encoding using the minimum symbol data characters for ECC 200
703 * @param $data (string) data to encode
704 * @return array of codewords
707 protected function getHighLevelEncoding ( $data ) {
708 // STEP A. Start in ASCII encodation.
709 $enc = ENC_ASCII
; // current encoding mode
710 $pos = 0 ; // current position
711 $cw = array (); // array of codewords to be returned
712 $cw_num = 0 ; // number of data codewords
713 $data_lenght = strlen ( $data ); // number of chars
714 while ( $pos < $data_lenght ) {
715 // set last used encoding
716 $this- > last_enc
= $enc ;
718 case ENC_ASCII
: { // STEP B. While in ASCII encodation
719 if (( $data_lenght > 1 ) AND ( $pos < ( $data_lenght - 1 )) AND ( $this- > isCharMode ( ord ( $data [ $pos ]), ENC_ASCII_NUM
) AND $this- > isCharMode ( ord ( $data [ $pos +
1 ]), ENC_ASCII_NUM
))) {
720 // 1. If the next data sequence is at least 2 consecutive digits, encode the next two digits as a double digit in ASCII mode.
721 $cw [] = ( intval ( substr ( $data , $pos , 2 )) +
130 );
725 // 2. If the look-ahead test (starting at step J) indicates another mode, switch to that mode.
726 $newenc = $this- > lookAheadTest ( $data , $pos , $enc );
727 if ( $newenc != $enc ) {
728 // switch to new encoding
730 $cw [] = $this- > getSwitchEncodingCodeword ( $enc );
734 $chr = ord ( $data [ $pos ]);
736 if ( $this- > isCharMode ( $chr , ENC_ASCII_EXT
)) {
737 // 3. If the next data character is extended ASCII (greater than 127) encode it in ASCII mode first using the Upper Shift (value 235) character.
739 $cw [] = ( $chr - 127 );
742 // 4. Otherwise process the next data character in ASCII encodation.
750 case ENC_C40
: // Upper-case alphanumeric
751 case ENC_TXT
: // Lower-case alphanumeric
752 case ENC_X12
: { // ANSI X12
757 $set_id = $this- > chset_id
[ $enc ];
758 // get basic charset for current encoding
759 $charset = $this- > chset
[ $set_id ];
761 // 2. process the next character in C40 encodation.
762 $chr = ord ( $data [ $epos ]);
764 // check for extended character
766 if ( $enc == ENC_X12
) {
769 $chr = ( $chr & 0x7f );
770 $temp_cw [] = 1 ; // shift 2
771 $temp_cw [] = 30 ; // upper shift
774 if ( isset ( $charset [ $chr ])) {
775 $temp_cw [] = $charset [ $chr ];
778 if ( isset ( $this- > chset
[ 'SH1' ][ $chr ])) {
779 $temp_cw [] = 0 ; // shift 1
780 $shiftset = $this- > chset
[ 'SH1' ];
781 } elseif ( isset ( $chr , $this- > chset
[ 'SH2' ][ $chr ])) {
782 $temp_cw [] = 1 ; // shift 2
783 $shiftset = $this- > chset
[ 'SH2' ];
784 } elseif (( $enc == ENC_C40
) AND isset ( $this- > chset
[ 'S3C' ][ $chr ])) {
785 $temp_cw [] = 2 ; // shift 3
786 $shiftset = $this- > chset
[ 'S3C' ];
787 } elseif (( $enc == ENC_TXT
) AND isset ( $this- > chset
[ 'S3T' ][ $chr ])) {
788 $temp_cw [] = 2 ; // shift 3
789 $shiftset = $this- > chset
[ 'S3T' ];
793 $temp_cw [] = $shiftset [ $chr ];
797 $c1 = array_shift ( $temp_cw );
798 $c2 = array_shift ( $temp_cw );
799 $c3 = array_shift ( $temp_cw );
801 $tmp = (( 1600 * $c1 ) +
( 40 * $c2 ) +
$c3 +
1 );
803 $cw [] = ( $tmp %
256 );
806 // 1. If the C40 encoding is at the point of starting a new double symbol character and if the look-ahead test (starting at step J) indicates another mode, switch to that mode.
807 $newenc = $this- > lookAheadTest ( $data , $pos , $enc );
808 if ( $newenc != $enc ) {
809 // switch to new encoding
811 if ( $enc != ENC_ASCII
) {
812 // set unlatch character
813 $cw [] = $this- > getSwitchEncodingCodeword ( ENC_ASCII
);
816 $cw [] = $this- > getSwitchEncodingCodeword ( $enc );
823 } while (( $p > 0 ) AND ( $epos < $data_lenght ));
824 // process last data (if any)
826 // get remaining number of data symbols
827 $cwr = ( $this- > getMaxDataCodewords ( $cw_num ) - $cw_num );
828 if (( $cwr == 1 ) AND ( $p == 1 )) {
829 // d. If one symbol character remains and one C40 value (data character) remains to be encoded
830 $c1 = array_shift ( $temp_cw );
836 $this- > last_enc
= $enc ;
837 } elseif (( $cwr == 2 ) AND ( $p == 1 )) {
838 // c. If two symbol characters remain and only one C40 value (data character) remains to be encoded
839 $c1 = array_shift ( $temp_cw );
846 $this- > last_enc
= $enc ;
847 } elseif (( $cwr == 2 ) AND ( $p == 2 )) {
848 // b. If two symbol characters remain and two C40 values remain to be encoded
849 $c1 = array_shift ( $temp_cw );
850 $c2 = array_shift ( $temp_cw );
852 $tmp = (( 1600 * $c1 ) +
( 40 * $c2 ) +
1 );
854 $cw [] = ( $tmp %
256 );
858 $this- > last_enc
= $enc ;
860 // switch to ASCII encoding
861 if ( $enc != ENC_ASCII
) {
863 $this- > last_enc
= $enc ;
864 $cw [] = $this- > getSwitchEncodingCodeword ( $enc );
872 case ENC_EDF
: { // F. While in EDIFACT (EDF) encodation
873 // initialize temporary array with 0 lenght
879 // 2. process the next character in EDIFACT encodation.
880 $chr = ord ( $data [ $epos ]);
881 if ( $this- > isCharMode ( $chr , ENC_EDF
)) {
886 if (( $field_lenght == 4 ) OR ( $epos == $data_lenght ) OR ! $this- > isCharMode ( $chr , ENC_EDF
)) {
887 if (( $epos == $data_lenght ) AND ( $field_lenght < 3 )) {
889 $cw [] = $this- > getSwitchEncodingCodeword ( $enc );
893 if ( $field_lenght < 4 ) {
894 // set unlatch character
897 // fill empty characters
898 for ( $i = $field_lenght ; $i < 4 ; ++
$i ) {
902 $this- > last_enc
= $enc ;
904 // encodes four data characters in three codewords
905 $tcw = (( $temp_cw [ 0 ] & 0x3F ) << 2 ) +
(( $temp_cw [ 1 ] & 0x30 ) >> 4 );
910 $tcw = (( $temp_cw [ 1 ] & 0x0F ) << 4 ) +
(( $temp_cw [ 2 ] & 0x3C ) >> 2 );
915 $tcw = (( $temp_cw [ 2 ] & 0x03 ) << 6 ) +
( $temp_cw [ 3 ] & 0x3F );
923 if ( $enc == ENC_ASCII
) {
924 break ; // exit from EDIFACT mode
927 } while ( $epos < $data_lenght );
930 case ENC_BASE256
: { // G. While in Base 256 (B256) encodation
931 // initialize temporary array with 0 lenght
934 while (( $pos < $data_lenght ) AND ( $field_lenght <= 1555 )) {
935 $newenc = $this- > lookAheadTest ( $data , $pos , $enc );
936 if ( $newenc != $enc ) {
937 // 1. If the look-ahead test (starting at step J) indicates another mode, switch to that mode.
939 break ; // exit from B256 mode
941 // 2. Otherwise, process the next character in Base 256 encodation.
942 $chr = ord ( $data [ $pos ]);
949 if ( $field_lenght <= 249 ) {
950 $cw [] = $this- > get255StateCodeword ( $field_lenght , ( $cw_num +
1 ));
953 $cw [] = $this- > get255StateCodeword (( floor ( $field_lenght / 250 ) +
249 ), ( $cw_num +
1 ));
954 $cw [] = $this- > get255StateCodeword (( $field_lenght %
250 ), ( $cw_num +
2 ));
957 if (! empty ( $temp_cw )) {
959 foreach ( $temp_cw as $p => $cht ) {
960 $cw [] = $this- > get255StateCodeword ( $cht , ( $cw_num +
$p +
1 ));
965 } // end of switch enc
971 * Places "chr+bit" with appropriate wrapping within array[].
972 * (Annex F - ECC 200 symbol character placement)
973 * @param $marr (array) Array of symbols.
974 * @param $nrow (int) Number of rows.
975 * @param $ncol (int) Number of columns.
976 * @param $row (int) Row number.
977 * @param $col (int) Column number.
978 * @param $chr (int) Char byte.
979 * @param $bit (int) Bit.
983 protected function placeModule ( $marr , $nrow , $ncol , $row , $col , $chr , $bit ) {
986 $col +
= ( 4 - (( $nrow +
4 ) %
8 ));
990 $row +
= ( 4 - (( $ncol +
4 ) %
8 ));
992 $marr [(( $row * $ncol ) +
$col )] = (( 10 * $chr ) +
$bit );
997 * Places the 8 bits of a utah-shaped symbol character.
998 * (Annex F - ECC 200 symbol character placement)
999 * @param $marr (array) Array of symbols.
1000 * @param $nrow (int) Number of rows.
1001 * @param $ncol (int) Number of columns.
1002 * @param $row (int) Row number.
1003 * @param $col (int) Column number.
1004 * @param $chr (int) Char byte.
1008 protected function placeUtah ( $marr , $nrow , $ncol , $row , $col , $chr ) {
1009 $marr = $this- > placeModule ( $marr , $nrow , $ncol , $row-2 , $col-2 , $chr , 1 );
1010 $marr = $this- > placeModule ( $marr , $nrow , $ncol , $row-2 , $col-1 , $chr , 2 );
1011 $marr = $this- > placeModule ( $marr , $nrow , $ncol , $row-1 , $col-2 , $chr , 3 );
1012 $marr = $this- > placeModule ( $marr , $nrow , $ncol , $row-1 , $col-1 , $chr , 4 );
1013 $marr = $this- > placeModule ( $marr , $nrow , $ncol , $row-1 , $col , $chr , 5 );
1014 $marr = $this- > placeModule ( $marr , $nrow , $ncol , $row , $col-2 , $chr , 6 );
1015 $marr = $this- > placeModule ( $marr , $nrow , $ncol , $row , $col-1 , $chr , 7 );
1016 $marr = $this- > placeModule ( $marr , $nrow , $ncol , $row , $col , $chr , 8 );
1021 * Places the 8 bits of the first special corner case.
1022 * (Annex F - ECC 200 symbol character placement)
1023 * @param $marr (array) Array of symbols.
1024 * @param $nrow (int) Number of rows.
1025 * @param $ncol (int) Number of columns.
1026 * @param $chr (int) Char byte.
1030 protected function placeCornerA ( $marr , $nrow , $ncol , $chr ) {
1031 $marr = $this- > placeModule ( $marr , $nrow , $ncol , $nrow-1 , 0 , $chr , 1 );
1032 $marr = $this- > placeModule ( $marr , $nrow , $ncol , $nrow-1 , 1 , $chr , 2 );
1033 $marr = $this- > placeModule ( $marr , $nrow , $ncol , $nrow-1 , 2 , $chr , 3 );
1034 $marr = $this- > placeModule ( $marr , $nrow , $ncol , 0 , $ncol-2 , $chr , 4 );
1035 $marr = $this- > placeModule ( $marr , $nrow , $ncol , 0 , $ncol-1 , $chr , 5 );
1036 $marr = $this- > placeModule ( $marr , $nrow , $ncol , 1 , $ncol-1 , $chr , 6 );
1037 $marr = $this- > placeModule ( $marr , $nrow , $ncol , 2 , $ncol-1 , $chr , 7 );
1038 $marr = $this- > placeModule ( $marr , $nrow , $ncol , 3 , $ncol-1 , $chr , 8 );
1043 * Places the 8 bits of the second special corner case.
1044 * (Annex F - ECC 200 symbol character placement)
1045 * @param $marr (array) Array of symbols.
1046 * @param $nrow (int) Number of rows.
1047 * @param $ncol (int) Number of columns.
1048 * @param $chr (int) Char byte.
1052 protected function placeCornerB ( $marr , $nrow , $ncol , $chr ) {
1053 $marr = $this- > placeModule ( $marr , $nrow , $ncol , $nrow-3 , 0 , $chr , 1 );
1054 $marr = $this- > placeModule ( $marr , $nrow , $ncol , $nrow-2 , 0 , $chr , 2 );
1055 $marr = $this- > placeModule ( $marr , $nrow , $ncol , $nrow-1 , 0 , $chr , 3 );
1056 $marr = $this- > placeModule ( $marr , $nrow , $ncol , 0 , $ncol-4 , $chr , 4 );
1057 $marr = $this- > placeModule ( $marr , $nrow , $ncol , 0 , $ncol-3 , $chr , 5 );
1058 $marr = $this- > placeModule ( $marr , $nrow , $ncol , 0 , $ncol-2 , $chr , 6 );
1059 $marr = $this- > placeModule ( $marr , $nrow , $ncol , 0 , $ncol-1 , $chr , 7 );
1060 $marr = $this- > placeModule ( $marr , $nrow , $ncol , 1 , $ncol-1 , $chr , 8 );
1065 * Places the 8 bits of the third special corner case.
1066 * (Annex F - ECC 200 symbol character placement)
1067 * @param $marr (array) Array of symbols.
1068 * @param $nrow (int) Number of rows.
1069 * @param $ncol (int) Number of columns.
1070 * @param $chr (int) Char byte.
1074 protected function placeCornerC ( $marr , $nrow , $ncol , $chr ) {
1075 $marr = $this- > placeModule ( $marr , $nrow , $ncol , $nrow-3 , 0 , $chr , 1 );
1076 $marr = $this- > placeModule ( $marr , $nrow , $ncol , $nrow-2 , 0 , $chr , 2 );
1077 $marr = $this- > placeModule ( $marr , $nrow , $ncol , $nrow-1 , 0 , $chr , 3 );
1078 $marr = $this- > placeModule ( $marr , $nrow , $ncol , 0 , $ncol-2 , $chr , 4 );
1079 $marr = $this- > placeModule ( $marr , $nrow , $ncol , 0 , $ncol-1 , $chr , 5 );
1080 $marr = $this- > placeModule ( $marr , $nrow , $ncol , 1 , $ncol-1 , $chr , 6 );
1081 $marr = $this- > placeModule ( $marr , $nrow , $ncol , 2 , $ncol-1 , $chr , 7 );
1082 $marr = $this- > placeModule ( $marr , $nrow , $ncol , 3 , $ncol-1 , $chr , 8 );
1087 * Places the 8 bits of the fourth special corner case.
1088 * (Annex F - ECC 200 symbol character placement)
1089 * @param $marr (array) Array of symbols.
1090 * @param $nrow (int) Number of rows.
1091 * @param $ncol (int) Number of columns.
1092 * @param $chr (int) Char byte.
1096 protected function placeCornerD ( $marr , $nrow , $ncol , $chr ) {
1097 $marr = $this- > placeModule ( $marr , $nrow , $ncol , $nrow-1 , 0 , $chr , 1 );
1098 $marr = $this- > placeModule ( $marr , $nrow , $ncol , $nrow-1 , $ncol-1 , $chr , 2 );
1099 $marr = $this- > placeModule ( $marr , $nrow , $ncol , 0 , $ncol-3 , $chr , 3 );
1100 $marr = $this- > placeModule ( $marr , $nrow , $ncol , 0 , $ncol-2 , $chr , 4 );
1101 $marr = $this- > placeModule ( $marr , $nrow , $ncol , 0 , $ncol-1 , $chr , 5 );
1102 $marr = $this- > placeModule ( $marr , $nrow , $ncol , 1 , $ncol-3 , $chr , 6 );
1103 $marr = $this- > placeModule ( $marr , $nrow , $ncol , 1 , $ncol-2 , $chr , 7 );
1104 $marr = $this- > placeModule ( $marr , $nrow , $ncol , 1 , $ncol-1 , $chr , 8 );
1109 * Build a placement map.
1110 * (Annex F - ECC 200 symbol character placement)
1111 * @param $nrow (int) Number of rows.
1112 * @param $ncol (int) Number of columns.
1116 protected function getPlacementMap ( $nrow , $ncol ) {
1117 // initialize array with zeros
1118 $marr = array_fill ( 0 , ( $nrow * $ncol ), 0 );
1119 // set starting values
1124 // repeatedly first check for one of the special corner cases, then
1125 if (( $row == $nrow ) AND ( $col == 0 )) {
1126 $marr = $this- > placeCornerA ( $marr , $nrow , $ncol , $chr );
1129 if (( $row == ( $nrow - 2 )) AND ( $col == 0 ) AND ( $ncol %
4 )) {
1130 $marr = $this- > placeCornerB ( $marr , $nrow , $ncol , $chr );
1133 if (( $row == ( $nrow - 2 )) AND ( $col == 0 ) AND (( $ncol %
8 ) == 4 )) {
1134 $marr = $this- > placeCornerC ( $marr , $nrow , $ncol , $chr );
1137 if (( $row == ( $nrow +
4 )) AND ( $col == 2 ) AND (!( $ncol %
8 ))) {
1138 $marr = $this- > placeCornerD ( $marr , $nrow , $ncol , $chr );
1141 // sweep upward diagonally, inserting successive characters,
1143 if (( $row < $nrow ) AND ( $col >= 0 ) AND (! $marr [(( $row * $ncol ) +
$col )])) {
1144 $marr = $this- > placeUtah ( $marr , $nrow , $ncol , $row , $col , $chr );
1149 } while (( $row >= 0 ) AND ( $col < $ncol ));
1152 // & then sweep downward diagonally, inserting successive characters,...
1154 if (( $row >= 0 ) AND ( $col < $ncol ) AND (! $marr [(( $row * $ncol ) +
$col )])) {
1155 $marr = $this- > placeUtah ( $marr , $nrow , $ncol , $row , $col , $chr );
1160 } while (( $row < $nrow ) AND ( $col >= 0 ));
1163 // ... until the entire array is scanned
1164 } while (( $row < $nrow ) OR ( $col < $ncol ));
1165 // lastly, if the lower righthand corner is untouched, fill in fixed pattern
1166 if (! $marr [(( $nrow * $ncol ) - 1 )]) {
1167 $marr [(( $nrow * $ncol ) - 1 )] = 1 ;
1168 $marr [(( $nrow * $ncol ) - $ncol - 2 )] = 1 ;
1173 } // end DataMatrix class
1174 //============================================================+
1176 //============================================================+