PHPIndex

This page lists files in the current directory. You can view content, get download/execute commands for Wget, Curl, or PowerShell, or filter the list using wildcards (e.g., `*.sh`).

Data.php
wget 'https://lists2.roe3.org/hesk/inc/tecnick/Barcode/Type/Square/Datamatrix/Data.php'
View Content
<?php
/**
 * Data.php
 *
 * @since       2015-02-21
 * @category    Library
 * @package     Barcode
 * @author      Nicola Asuni <info@tecnick.com>
 * @copyright   2010-2016 Nicola Asuni - Tecnick.com LTD
 * @license     http://www.gnu.org/copyleft/lesser.html GNU-LGPL v3 (see LICENSE.TXT)
 * @link        https://github.com/tecnickcom/tc-lib-barcode
 *
 * This file is part of tc-lib-barcode software library.
 */

namespace Com\Tecnick\Barcode\Type\Square\Datamatrix;

use \Com\Tecnick\Barcode\Exception as BarcodeException;

/**
 * Com\Tecnick\Barcode\Type\Square\Datamatrix\Data
 *
 * Data for Datamatrix Barcode type class
 *
 * @since       2015-02-21
 * @category    Library
 * @package     Barcode
 * @author      Nicola Asuni <info@tecnick.com>
 * @copyright   2010-2016 Nicola Asuni - Tecnick.com LTD
 * @license     http://www.gnu.org/copyleft/lesser.html GNU-LGPL v3 (see LICENSE.TXT)
 * @link        https://github.com/tecnickcom/tc-lib-barcode
 */
class Data
{
    /**
     * ASCII encoding: ASCII character 0 to 127 (1 byte per CW)
     */
    const ENC_ASCII = 0;

    /**
     * C40 encoding: Upper-case alphanumeric (3/2 bytes per CW)
     */
    const ENC_C40 = 1;

    /**
     * TEXT encoding: Lower-case alphanumeric (3/2 bytes per CW)
     */
    const ENC_TXT = 2;

    /**
     * X12 encoding: ANSI X12 (3/2 byte per CW)
     */
    const ENC_X12 = 3;

    /**
     * EDIFACT encoding: ASCII character 32 to 94 (4/3 bytes per CW)
     */
    const ENC_EDF = 4;

    /**
     * BASE 256 encoding: ASCII character 0 to 255 (1 byte per CW)
     */
    const ENC_BASE256 = 5;

    /**
     * ASCII extended encoding: ASCII character 128 to 255 (1/2 byte per CW)
     */
    const ENC_ASCII_EXT = 6;

    /**
     * ASCII number encoding: ASCII digits (2 bytes per CW)
     */
    const ENC_ASCII_NUM = 7;

    /**
     * Table of Data Matrix ECC 200 Symbol Attributes:
     * <ul><li>SHAPE<ul>
     * <li>total matrix rows (including finder pattern)</li>
     * <li>total matrix cols (including finder pattern)</li>
     * <li>total matrix rows (without finder pattern)</li>
     * <li>total matrix cols (without finder pattern)</li>
     * <li>region data rows (with finder pattern)</li>
     * <li>region data col (with finder pattern)</li>
     * <li>region data rows (without finder pattern)</li>
     * <li>region data col (without finder pattern)</li>
     * <li>horizontal regions</li>
     * <li>vertical regions</li>
     * <li>regions</li>
     * <li>data codewords</li>
     * <li>error codewords</li>
     * <li>blocks</li>
     * <li>data codewords per block</li>
     * <li>error codewords per block</li>
     * </ul></li></ul>
     *
     * @var array
     */
    public static $symbattr = array(
        'S' => array( // square form
            // 10x10
            array(0x00a,0x00a,0x008,0x008,0x00a,0x00a,0x008,0x008,0x001,0x001,0x001,0x003,0x005,0x001,0x003,0x005),
            // 12x12
            array(0x00c,0x00c,0x00a,0x00a,0x00c,0x00c,0x00a,0x00a,0x001,0x001,0x001,0x005,0x007,0x001,0x005,0x007),
            // 14x14
            array(0x00e,0x00e,0x00c,0x00c,0x00e,0x00e,0x00c,0x00c,0x001,0x001,0x001,0x008,0x00a,0x001,0x008,0x00a),
            // 16x16
            array(0x010,0x010,0x00e,0x00e,0x010,0x010,0x00e,0x00e,0x001,0x001,0x001,0x00c,0x00c,0x001,0x00c,0x00c),
            // 18x18
            array(0x012,0x012,0x010,0x010,0x012,0x012,0x010,0x010,0x001,0x001,0x001,0x012,0x00e,0x001,0x012,0x00e),
            // 20x20
            array(0x014,0x014,0x012,0x012,0x014,0x014,0x012,0x012,0x001,0x001,0x001,0x016,0x012,0x001,0x016,0x012),
            // 22x22
            array(0x016,0x016,0x014,0x014,0x016,0x016,0x014,0x014,0x001,0x001,0x001,0x01e,0x014,0x001,0x01e,0x014),
            // 24x24
            array(0x018,0x018,0x016,0x016,0x018,0x018,0x016,0x016,0x001,0x001,0x001,0x024,0x018,0x001,0x024,0x018),
            // 26x26
            array(0x01a,0x01a,0x018,0x018,0x01a,0x01a,0x018,0x018,0x001,0x001,0x001,0x02c,0x01c,0x001,0x02c,0x01c),
            // 32x32
            array(0x020,0x020,0x01c,0x01c,0x010,0x010,0x00e,0x00e,0x002,0x002,0x004,0x03e,0x024,0x001,0x03e,0x024),
            // 36x36
            array(0x024,0x024,0x020,0x020,0x012,0x012,0x010,0x010,0x002,0x002,0x004,0x056,0x02a,0x001,0x056,0x02a),
            // 40x40
            array(0x028,0x028,0x024,0x024,0x014,0x014,0x012,0x012,0x002,0x002,0x004,0x072,0x030,0x001,0x072,0x030),
            // 44x44
            array(0x02c,0x02c,0x028,0x028,0x016,0x016,0x014,0x014,0x002,0x002,0x004,0x090,0x038,0x001,0x090,0x038),
            // 48x48
            array(0x030,0x030,0x02c,0x02c,0x018,0x018,0x016,0x016,0x002,0x002,0x004,0x0ae,0x044,0x001,0x0ae,0x044),
            // 52x52
            array(0x034,0x034,0x030,0x030,0x01a,0x01a,0x018,0x018,0x002,0x002,0x004,0x0cc,0x054,0x002,0x066,0x02a),
            // 64x64
            array(0x040,0x040,0x038,0x038,0x010,0x010,0x00e,0x00e,0x004,0x004,0x010,0x118,0x070,0x002,0x08c,0x038),
            // 72x72
            array(0x048,0x048,0x040,0x040,0x012,0x012,0x010,0x010,0x004,0x004,0x010,0x170,0x090,0x004,0x05c,0x024),
            // 80x80
            array(0x050,0x050,0x048,0x048,0x014,0x014,0x012,0x012,0x004,0x004,0x010,0x1c8,0x0c0,0x004,0x072,0x030),
            // 88x88
            array(0x058,0x058,0x050,0x050,0x016,0x016,0x014,0x014,0x004,0x004,0x010,0x240,0x0e0,0x004,0x090,0x038),
            // 96x96
            array(0x060,0x060,0x058,0x058,0x018,0x018,0x016,0x016,0x004,0x004,0x010,0x2b8,0x110,0x004,0x0ae,0x044),
            // 104x104
            array(0x068,0x068,0x060,0x060,0x01a,0x01a,0x018,0x018,0x004,0x004,0x010,0x330,0x150,0x006,0x088,0x038),
            // 120x120
            array(0x078,0x078,0x06c,0x06c,0x014,0x014,0x012,0x012,0x006,0x006,0x024,0x41a,0x198,0x006,0x0af,0x044),
            // 132x132
            array(0x084,0x084,0x078,0x078,0x016,0x016,0x014,0x014,0x006,0x006,0x024,0x518,0x1f0,0x008,0x0a3,0x03e),
            // 144x144
            array(0x090,0x090,0x084,0x084,0x018,0x018,0x016,0x016,0x006,0x006,0x024,0x618,0x26c,0x00a,0x09c,0x03e)
        ),
        'R' => array( // rectangular form
            // 8x18
            array(0x008,0x012,0x006,0x010,0x008,0x012,0x006,0x010,0x001,0x001,0x001,0x005,0x007,0x001,0x005,0x007),
            // 8x32
            array(0x008,0x020,0x006,0x01c,0x008,0x010,0x006,0x00e,0x001,0x002,0x002,0x00a,0x00b,0x001,0x00a,0x00b),
            // 12x26
            array(0x00c,0x01a,0x00a,0x018,0x00c,0x01a,0x00a,0x018,0x001,0x001,0x001,0x010,0x00e,0x001,0x010,0x00e),
            // 12x36
            array(0x00c,0x024,0x00a,0x020,0x00c,0x012,0x00a,0x010,0x001,0x002,0x002,0x00c,0x012,0x001,0x00c,0x012),
            // 16x36
            array(0x010,0x024,0x00e,0x020,0x010,0x012,0x00e,0x010,0x001,0x002,0x002,0x020,0x018,0x001,0x020,0x018),
            // 16x48
            array(0x010,0x030,0x00e,0x02c,0x010,0x018,0x00e,0x016,0x001,0x002,0x002,0x031,0x01c,0x001,0x031,0x01c)
        )
    );

    /**
     * Map encodation modes whit character sets.
     *
     * @var array
     */
    public static $chset_id = array(
        self::ENC_C40 => 'C40',
        self::ENC_TXT => 'TXT',
        self::ENC_X12 => 'X12'
    );

    /**
     * Basic set of characters for each encodation mode.
     *
     * @var array
     */
    public static $chset = array(
    'C40' => array( // Basic set for C40 ----------------------------------------------------------------------------
        'S1'=>0x00,'S2'=>0x01,'S3'=>0x02,0x20=>0x03,0x30=>0x04,0x31=>0x05,0x32=>0x06,0x33=>0x07,0x34=>0x08,0x35=>0x09,
        0x36=>0x0a,0x37=>0x0b,0x38=>0x0c,0x39=>0x0d,0x41=>0x0e,0x42=>0x0f,0x43=>0x10,0x44=>0x11,0x45=>0x12,0x46=>0x13,
        0x47=>0x14,0x48=>0x15,0x49=>0x16,0x4a=>0x17,0x4b=>0x18,0x4c=>0x19,0x4d=>0x1a,0x4e=>0x1b,0x4f=>0x1c,0x50=>0x1d,
        0x51=>0x1e,0x52=>0x1f,0x53=>0x20,0x54=>0x21,0x55=>0x22,0x56=>0x23,0x57=>0x24,0x58=>0x25,0x59=>0x26,0x5a=>0x27),
    'TXT' => array( // Basic set for TEXT ---------------------------------------------------------------------------
        'S1'=>0x00,'S2'=>0x01,'S3'=>0x02,0x20=>0x03,0x30=>0x04,0x31=>0x05,0x32=>0x06,0x33=>0x07,0x34=>0x08,0x35=>0x09,
        0x36=>0x0a,0x37=>0x0b,0x38=>0x0c,0x39=>0x0d,0x61=>0x0e,0x62=>0x0f,0x63=>0x10,0x64=>0x11,0x65=>0x12,0x66=>0x13,
        0x67=>0x14,0x68=>0x15,0x69=>0x16,0x6a=>0x17,0x6b=>0x18,0x6c=>0x19,0x6d=>0x1a,0x6e=>0x1b,0x6f=>0x1c,0x70=>0x1d,
        0x71=>0x1e,0x72=>0x1f,0x73=>0x20,0x74=>0x21,0x75=>0x22,0x76=>0x23,0x77=>0x24,0x78=>0x25,0x79=>0x26,0x7a=>0x27),
    'SH1' => array( // Shift 1 set ----------------------------------------------------------------------------------
        0x00=>0x00,0x01=>0x01,0x02=>0x02,0x03=>0x03,0x04=>0x04,0x05=>0x05,0x06=>0x06,0x07=>0x07,0x08=>0x08,0x09=>0x09,
        0x0a=>0x0a,0x0b=>0x0b,0x0c=>0x0c,0x0d=>0x0d,0x0e=>0x0e,0x0f=>0x0f,0x10=>0x10,0x11=>0x11,0x12=>0x12,0x13=>0x13,
        0x14=>0x14,0x15=>0x15,0x16=>0x16,0x17=>0x17,0x18=>0x18,0x19=>0x19,0x1a=>0x1a,0x1b=>0x1b,0x1c=>0x1c,0x1d=>0x1d,
        0x1e=>0x1e,0x1f=>0x1f),
    'SH2' => array( // Shift 2 set ----------------------------------------------------------------------------------
        0x21=>0x00,0x22=>0x01,0x23=>0x02,0x24=>0x03,0x25=>0x04,0x26=>0x05,0x27=>0x06,0x28=>0x07,0x29=>0x08,0x2a=>0x09,
        0x2b=>0x0a,0x2c=>0x0b,0x2d=>0x0c,0x2e=>0x0d,0x2f=>0x0e,0x3a=>0x0f,0x3b=>0x10,0x3c=>0x11,0x3d=>0x12,0x3e=>0x13,
        0x3f=>0x14,0x40=>0x15,0x5b=>0x16,0x5c=>0x17,0x5d=>0x18,0x5e=>0x19,0x5f=>0x1a,'F1'=>0x1b,'US'=>0x1e),
    'S3C' => array( // Shift 3 set for C40 --------------------------------------------------------------------------
        0x60=>0x00,0x61=>0x01,0x62=>0x02,0x63=>0x03,0x64=>0x04,0x65=>0x05,0x66=>0x06,0x67=>0x07,0x68=>0x08,0x69=>0x09,
        0x6a=>0x0a,0x6b=>0x0b,0x6c=>0x0c,0x6d=>0x0d,0x6e=>0x0e,0x6f=>0x0f,0x70=>0x10,0x71=>0x11,0x72=>0x12,0x73=>0x13,
        0x74=>0x14,0x75=>0x15,0x76=>0x16,0x77=>0x17,0x78=>0x18,0x79=>0x19,0x7a=>0x1a,0x7b=>0x1b,0x7c=>0x1c,0x7d=>0x1d,
        0x7e=>0x1e,0x7f=>0x1f),
    'S3T' => array( // Shift 3 set for TEXT -------------------------------------------------------------------------
        0x60=>0x00,0x41=>0x01,0x42=>0x02,0x43=>0x03,0x44=>0x04,0x45=>0x05,0x46=>0x06,0x47=>0x07,0x48=>0x08,0x49=>0x09,
        0x4a=>0x0a,0x4b=>0x0b,0x4c=>0x0c,0x4d=>0x0d,0x4e=>0x0e,0x4f=>0x0f,0x50=>0x10,0x51=>0x11,0x52=>0x12,0x53=>0x13,
        0x54=>0x14,0x55=>0x15,0x56=>0x16,0x57=>0x17,0x58=>0x18,0x59=>0x19,0x5a=>0x1a,0x7b=>0x1b,0x7c=>0x1c,0x7d=>0x1d,
        0x7e=>0x1e,0x7f=>0x1f),
    'X12' => array( // Set for X12 ----------------------------------------------------------------------------------
        0x0d=>0x00,0x2a=>0x01,0x3e=>0x02,0x20=>0x03,0x30=>0x04,0x31=>0x05,0x32=>0x06,0x33=>0x07,0x34=>0x08,0x35=>0x09,
        0x36=>0x0a,0x37=>0x0b,0x38=>0x0c,0x39=>0x0d,0x41=>0x0e,0x42=>0x0f,0x43=>0x10,0x44=>0x11,0x45=>0x12,0x46=>0x13,
        0x47=>0x14,0x48=>0x15,0x49=>0x16,0x4a=>0x17,0x4b=>0x18,0x4c=>0x19,0x4d=>0x1a,0x4e=>0x1b,0x4f=>0x1c,0x50=>0x1d,
        0x51=>0x1e,0x52=>0x1f,0x53=>0x20,0x54=>0x21,0x55=>0x22,0x56=>0x23,0x57=>0x24,0x58=>0x25,0x59=>0x26,0x5a=>0x27)
    );

    /**
     * Get the required codewords padding size
     *
     * @return array params
     *
     * @throws BarcodeException in case of error
     */
    public static function getPaddingSize($shape, $ncw)
    {
        foreach (Data::$symbattr[$shape] as $params) {
            if ($params[11] >= $ncw) {
                return $params;
            }
        }
        throw new BarcodeException('Unable to find the correct size');
    }
}
Encode.php
wget 'https://lists2.roe3.org/hesk/inc/tecnick/Barcode/Type/Square/Datamatrix/Encode.php'
View Content
<?php
/**
 * Encode.php
 *
 * @since       2015-02-21
 * @category    Library
 * @package     Barcode
 * @author      Nicola Asuni <info@tecnick.com>
 * @copyright   2015-2020 Nicola Asuni - Tecnick.com LTD
 * @license     http://www.gnu.org/copyleft/lesser.html GNU-LGPL v3 (see LICENSE.TXT)
 * @link        https://github.com/tecnickcom/tc-lib-barcode
 *
 * This file is part of tc-lib-barcode software library.
 */

namespace Com\Tecnick\Barcode\Type\Square\Datamatrix;

use \Com\Tecnick\Barcode\Exception as BarcodeException;
use \Com\Tecnick\Barcode\Type\Square\Datamatrix\Data;

/**
 * Com\Tecnick\Barcode\Type\Square\Datamatrix\Encode
 *
 * Datamatrix Barcode type class
 * DATAMATRIX (ISO/IEC 16022)
 *
 * @since       2015-02-21
 * @category    Library
 * @package     Barcode
 * @author      Nicola Asuni <info@tecnick.com>
 * @copyright   2015-2016 Nicola Asuni - Tecnick.com LTD
 * @license     http://www.gnu.org/copyleft/lesser.html GNU-LGPL v3 (see LICENSE.TXT)
 * @link        https://github.com/tecnickcom/tc-lib-barcode
 */
class Encode extends \Com\Tecnick\Barcode\Type\Square\Datamatrix\EncodeTxt
{
    /**
     * Store last used encoding for data codewords.
     *
     * @var int
     */
    public $last_enc;

    /**
     * Datamatrix shape key (S=square, R=rectangular)
     *
     * @var string
     */
    public $shape;

    /**
     * Initialize a new encode object
     *
     * @param string $shape Datamatrix shape key (S=square, R=rectangular)
     */
    public function __construct($shape = 'S')
    {
        $this->shape = $shape;
    }

    /**
     * Encode ASCII
     *
     * @param int    $cdw
     * @param int    $cdw_num
     * @param int    $pos
     * @param int    $data_length
     * @param string $data
     * @param int    $enc
     */
    public function encodeASCII(&$cdw, &$cdw_num, &$pos, &$data_length, &$data, &$enc)
    {
        if (($data_length > 1)
            && ($pos < ($data_length - 1))
            && ($this->isCharMode(ord($data[$pos]), Data::ENC_ASCII_NUM)
                && $this->isCharMode(ord($data[$pos + 1]), Data::ENC_ASCII_NUM)
            )
        ) {
            // 1. If the next data sequence is at least 2 consecutive digits,
            // encode the next two digits as a double digit in ASCII mode.
            $cdw[] = (intval(substr($data, $pos, 2)) + 130);
            ++$cdw_num;
            $pos += 2;
        } else {
            // 2. If the look-ahead test (starting at step J) indicates another mode, switch to that mode.
            $newenc = $this->lookAheadTest($data, $pos, $enc);
            if ($newenc != $enc) {
                // switch to new encoding
                $enc = $newenc;
                $cdw[] = $this->getSwitchEncodingCodeword($enc);
                ++$cdw_num;
            } else {
                // get new byte
                $chr = ord($data[$pos]);
                ++$pos;
                if ($this->isCharMode($chr, Data::ENC_ASCII_EXT)) {
                    // 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.
                    $cdw[] = 235;
                    $cdw[] = ($chr - 127);
                    $cdw_num += 2;
                } else {
                    // 4. Otherwise process the next data character in ASCII encodation.
                    $cdw[] = ($chr + 1);
                    ++$cdw_num;
                }
            }
        }
    }

    /**
     * Encode EDF4
     *
     * @param int    $epos
     * @param int    $cdw
     * @param int    $cdw_num
     * @param int    $pos
     * @param int    $data_length
     * @param int    $field_length
     * @param int    $enc
     * @param array  $temp_cw
     *
     * @return boolean true to break the loop
     */
    public function encodeEDFfour($epos, &$cdw, &$cdw_num, &$pos, &$data_length, &$field_length, &$enc, &$temp_cw)
    {
        if (($epos == $data_length)) {
            $enc = Data::ENC_ASCII;
            $params = Data::getPaddingSize($this->shape, ($cdw_num + $field_length));
            if (($params[11] - $cdw_num) > 2) {
                $cdw[] = $this->getSwitchEncodingCodeword($enc);
                ++$cdw_num;
            }
            return true;
        }
        if ($field_length < 4) {
            $enc = Data::ENC_ASCII;
            $this->last_enc = $enc;
            $params = Data::getPaddingSize($this->shape, ($cdw_num + $field_length + ($data_length - $epos)));
            if (($params[11] - $cdw_num) > 2) {
                // set unlatch character
                $temp_cw[] = 0x1f;
                ++$field_length;
                // fill empty characters
                for ($i = $field_length; $i < 4; ++$i) {
                    $temp_cw[] = 0;
                }
            } else {
                return true;
            }
        }
        // encodes four data characters in three codewords
        $cdw[] = (($temp_cw[0] & 0x3F) << 2) + (($temp_cw[1] & 0x30) >> 4);
        $cdw_num++;
        if ($field_length > 1) {
            $cdw[] = (($temp_cw[1] & 0x0F) << 4) + (($temp_cw[2] & 0x3C) >> 2);
            $cdw_num++;
        }
        if ($field_length > 2) {
            $cdw[] = (($temp_cw[2] & 0x03) << 6) + ($temp_cw[3] & 0x3F);
            $cdw_num++;
        }
        $temp_cw = array();
        $pos = $epos;
        $field_length = 0;
        if ($enc == Data::ENC_ASCII) {
            return true; // exit from EDIFACT mode
        }
        return false;
    }

    /**
     * Encode EDF
     *
     * @param int    $cdw
     * @param int    $cdw_num
     * @param int    $pos
     * @param int    $data_length
     * @param int    $field_length
     * @param string $data
     * @param int    $enc
     */
    public function encodeEDF(&$cdw, &$cdw_num, &$pos, &$data_length, &$field_length, &$data, &$enc)
    {
        // initialize temporary array with 0 length
        $temp_cw = array();
        $epos = $pos;
        $field_length = 0;
        do {
            // 2. process the next character in EDIFACT encodation.
            $chr = ord($data[$epos]);
            if ($this->isCharMode($chr, Data::ENC_EDF)) {
                ++$epos;
                $temp_cw[] = $chr;
                ++$field_length;
            }
            if (($field_length == 4)
                || ($epos == $data_length)
                || !$this->isCharMode($chr, Data::ENC_EDF)
            ) {
                if ($this->encodeEDFfour($epos, $cdw, $cdw_num, $pos, $data_length, $field_length, $enc, $temp_cw)) {
                    break;
                }
            }
        } while ($epos < $data_length);
    }

    /**
     * Encode Base256
     *
     * @param int    $cdw
     * @param int    $cdw_num
     * @param int    $pos
     * @param int    $data_length
     * @param int    $field_length
     * @param string $data
     * @param int    $enc
     */
    public function encodeBase256(&$cdw, &$cdw_num, &$pos, &$data_length, &$field_length, &$data, &$enc)
    {
        // initialize temporary array with 0 length
        $temp_cw = array();
        $field_length = 0;
        while (($pos < $data_length) && ($field_length <= 1555)) {
            $newenc = $this->lookAheadTest($data, $pos, $enc);
            if ($newenc != $enc) {
                // 1. If the look-ahead test (starting at step J)
                // indicates another mode, switch to that mode.
                $enc = $newenc;
                break; // exit from B256 mode
            } else {
                // 2. Otherwise, process the next character in Base 256 encodation.
                $chr = ord($data[$pos]);
                ++$pos;
                $temp_cw[] = $chr;
                ++$field_length;
            }
        }
        // set field length
        if ($field_length <= 249) {
            $cdw[] = $this->get255StateCodeword($field_length, ($cdw_num + 1));
            ++$cdw_num;
        } else {
            $cdw[] = $this->get255StateCodeword((floor($field_length / 250) + 249), ($cdw_num + 1));
            $cdw[] = $this->get255StateCodeword(($field_length % 250), ($cdw_num + 2));
            $cdw_num += 2;
        }
        if (!empty($temp_cw)) {
            // add B256 field
            foreach ($temp_cw as $cht) {
                $cdw[] = $this->get255StateCodeword($cht, ($cdw_num + 1));
                ++$cdw_num;
            }
        }
    }
}
EncodeTxt.php
wget 'https://lists2.roe3.org/hesk/inc/tecnick/Barcode/Type/Square/Datamatrix/EncodeTxt.php'
View Content
<?php
/**
 * EncodeTxt.php
 *
 * @since       2015-02-21
 * @category    Library
 * @package     Barcode
 * @author      Nicola Asuni <info@tecnick.com>
 * @copyright   2010-2020 Nicola Asuni - Tecnick.com LTD
 * @license     http://www.gnu.org/copyleft/lesser.html GNU-LGPL v3 (see LICENSE.TXT)
 * @link        https://github.com/tecnickcom/tc-lib-barcode
 *
 * This file is part of tc-lib-barcode software library.
 */

namespace Com\Tecnick\Barcode\Type\Square\Datamatrix;

use \Com\Tecnick\Barcode\Exception as BarcodeException;
use \Com\Tecnick\Barcode\Type\Square\Datamatrix\Data;

/**
 * Com\Tecnick\Barcode\Type\Square\Datamatrix\Encodetxt
 *
 * Datamatrix Barcode type class
 * DATAMATRIX (ISO/IEC 16022)
 *
 * @since       2015-02-21
 * @category    Library
 * @package     Barcode
 * @author      Nicola Asuni <info@tecnick.com>
 * @copyright   2010-2016 Nicola Asuni - Tecnick.com LTD
 * @license     http://www.gnu.org/copyleft/lesser.html GNU-LGPL v3 (see LICENSE.TXT)
 * @link        https://github.com/tecnickcom/tc-lib-barcode
 */
class EncodeTxt extends \Com\Tecnick\Barcode\Type\Square\Datamatrix\Steps
{
    /**
     * Encode TXTC40 shift
     *
     * @param int $chr
     * @param int $enc
     * @param int $temp_cw
     * @param int $ptr
     */
    public function encodeTXTC40shift(&$chr, &$enc, &$temp_cw, &$ptr)
    {
        if (isset(Data::$chset['SH1'][$chr])) {
            $temp_cw[] = 0; // shift 1
            $shiftset = Data::$chset['SH1'];
        } elseif (isset($chr, Data::$chset['SH2'][$chr])) {
            $temp_cw[] = 1; // shift 2
            $shiftset = Data::$chset['SH2'];
        } elseif (($enc == Data::ENC_C40) && isset(Data::$chset['S3C'][$chr])) {
            $temp_cw[] = 2; // shift 3
            $shiftset = Data::$chset['S3C'];
        } elseif (($enc == Data::ENC_TXT) && isset(Data::$chset['S3T'][$chr])) {
            $temp_cw[] = 2; // shift 3
            $shiftset = Data::$chset['S3T'];
        } else {
            throw new BarcodeException('Error');
        }
        $temp_cw[] = $shiftset[$chr];
        $ptr += 2;
    }

    /**
     * Encode TXTC40
     *
     * @param string $data
     * @param int    $enc
     * @param int    $temp_cw
     * @param int    $ptr
     * @param int    $epos
     * @param array  $charset
     *
     * @return int   Curent character code
     */
    public function encodeTXTC40(&$data, &$enc, &$temp_cw, &$ptr, &$epos, &$charset)
    {
        // 2. process the next character in C40 encodation.
        $chr = ord($data[$epos]);
        ++$epos;
        // check for extended character
        if ($chr & 0x80) {
            if ($enc == Data::ENC_X12) {
                throw new BarcodeException('TXTC40 Error');
            }
            $chr = ($chr & 0x7f);
            $temp_cw[] = 1; // shift 2
            $temp_cw[] = 30; // upper shift
            $ptr += 2;
        }
        if (isset($charset[$chr])) {
            $temp_cw[] = $charset[$chr];
            ++$ptr;
        } else {
            $this->encodeTXTC40shift($chr, $enc, $temp_cw, $ptr);
        }
        return $chr;
    }

    /**
     * Encode TXTC40 last
     * The following rules apply when only one or two symbol characters remain in the symbol
     * before the start of the error correction codewords.
     *
     * @param int    $chr
     * @param int    $cdw
     * @param int    $cdw_num
     * @param int    $enc
     * @param int    $temp_cw
     * @param int    $ptr
     * @param int    $epos
     */
    public function encodeTXTC40last($chr, &$cdw, &$cdw_num, &$enc, &$temp_cw, &$ptr, &$epos)
    {
        // get remaining number of data symbols
        $cdwr = ($this->getMaxDataCodewords($cdw_num + $ptr) - $cdw_num);
        if (($cdwr == 1) && ($ptr == 1)) {
            // d. If one symbol character remains and one
            // C40 value (data character) remains to be encoded
            $cdw[] = ($chr + 1);
            ++$cdw_num;
            $enc = Data::ENC_ASCII;
            $this->last_enc = $enc;
        } elseif (($cdwr == 2) && ($ptr == 1)) {
            // c. If two symbol characters remain and only one
            // C40 value (data character) remains to be encoded
            $cdw[] = 254;
            $cdw[] = ($chr + 1);
            $cdw_num += 2;
            $enc = Data::ENC_ASCII;
            $this->last_enc = $enc;
        } elseif (($cdwr == 2) && ($ptr == 2)) {
            // b. If two symbol characters remain and two C40 values remain to be encoded
            $ch1 = array_shift($temp_cw);
            $ch2 = array_shift($temp_cw);
            $ptr -= 2;
            $tmp = ((1600 * $ch1) + (40 * $ch2) + 1);
            $cdw[] = ($tmp >> 8);
            $cdw[] = ($tmp % 256);
            $cdw_num += 2;
            $enc = Data::ENC_ASCII;
            $this->last_enc = $enc;
        } else {
            // switch to ASCII encoding
            if ($enc != Data::ENC_ASCII) {
                $enc = Data::ENC_ASCII;
                $this->last_enc = $enc;
                $cdw[] = $this->getSwitchEncodingCodeword($enc);
                ++$cdw_num;
                $epos -= $ptr;
            }
        }
    }

    /**
     * Encode TXT
     *
     * @param int    $cdw
     * @param int    $cdw_num
     * @param int    $pos
     * @param int    $data_length
     * @param string $data
     * @param int    $enc
     */
    public function encodeTXT(&$cdw, &$cdw_num, &$pos, &$data_length, &$data, &$enc)
    {
        $temp_cw = array();
        $ptr = 0;
        $epos = $pos;
        // get charset ID
        $set_id = Data::$chset_id[$enc];
        // get basic charset for current encoding
        $charset = Data::$chset[$set_id];
        do {
            $chr = $this->encodeTXTC40($data, $enc, $temp_cw, $ptr, $epos, $charset);
            if ($ptr >= 3) {
                $ch1 = array_shift($temp_cw);
                $ch2 = array_shift($temp_cw);
                $ch3 = array_shift($temp_cw);
                $ptr -= 3;
                $tmp = ((1600 * $ch1) + (40 * $ch2) + $ch3 + 1);
                $cdw[] = ($tmp >> 8);
                $cdw[] = ($tmp % 256);
                $cdw_num += 2;
                $pos = $epos;
                // 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.
                $newenc = $this->lookAheadTest($data, $pos, $enc);
                if ($newenc != $enc) {
                    // switch to new encoding
                    $enc = $newenc;
                    if ($enc != Data::ENC_ASCII) {
                        // set unlatch character
                        $cdw[] = $this->getSwitchEncodingCodeword(Data::ENC_ASCII);
                        ++$cdw_num;
                    }
                    $cdw[] = $this->getSwitchEncodingCodeword($enc);
                    ++$cdw_num;
                    $pos -= $ptr;
                    $ptr = 0;
                    break;
                }
            }
        } while (($ptr > 0) && ($epos < $data_length));
        // process last data (if any)
        if ($ptr > 0) {
            $this->encodeTXTC40last($chr, $cdw, $cdw_num, $enc, $temp_cw, $ptr, $epos);
            $pos = $epos;
        }
    }
}
ErrorCorrection.php
wget 'https://lists2.roe3.org/hesk/inc/tecnick/Barcode/Type/Square/Datamatrix/ErrorCorrection.php'
View Content
<?php
/**
 * ErrorCorrection.php
 *
 * @since       2015-02-21
 * @category    Library
 * @package     Barcode
 * @author      Nicola Asuni <info@tecnick.com>
 * @copyright   2010-2016 Nicola Asuni - Tecnick.com LTD
 * @license     http://www.gnu.org/copyleft/lesser.html GNU-LGPL v3 (see LICENSE.TXT)
 * @link        https://github.com/tecnickcom/tc-lib-barcode
 *
 * This file is part of tc-lib-barcode software library.
 */

namespace Com\Tecnick\Barcode\Type\Square\Datamatrix;

/**
 * Com\Tecnick\Barcode\Type\Square\Datamatrix\ErrorCorrection
 *
 * Error correction methods and other utilities for Datamatrix Barcode type class
 *
 * @since       2015-02-21
 * @category    Library
 * @package     Barcode
 * @author      Nicola Asuni <info@tecnick.com>
 * @copyright   2010-2016 Nicola Asuni - Tecnick.com LTD
 * @license     http://www.gnu.org/copyleft/lesser.html GNU-LGPL v3 (see LICENSE.TXT)
 * @link        https://github.com/tecnickcom/tc-lib-barcode
 */
class ErrorCorrection
{
    /**
     * Product of two numbers in a Power-of-Two Galois Field
     *
     * @param int   $numa First number to multiply.
     * @param int   $numb Second number to multiply.
     * @param array $log  Log table.
     * @param array $alog Anti-Log table.
     * @param array $ngf  Number of Factors of the Reed-Solomon polynomial.
     *
     * @return int product
     */
    protected function getGFProduct($numa, $numb, $log, $alog, $ngf)
    {
        if (($numa == 0) || ($numb == 0)) {
            return 0;
        }
        return ($alog[($log[$numa] + $log[$numb]) % ($ngf - 1)]);
    }

    /**
     * Add error correction codewords to data codewords array (ANNEX E).
     *
     * @param array $wdc Array of datacodewords.
     * @param int   $nbk Number of blocks.
     * @param int   $ncw Number of data codewords per block.
     * @param int   $ncc Number of correction codewords per block.
     * @param int   $ngf Number of fields on log/antilog table (power of 2).
     * @param int   $vpp The value of its prime modulus polynomial (301 for ECC200).
     *
     * @return array data codewords + error codewords
     */
    public function getErrorCorrection($wdc, $nbk, $ncw, $ncc, $ngf = 256, $vpp = 301)
    {
        // generate the log ($log) and antilog ($alog) tables
        $log = array(0);
        $alog = array(1);
        $this->genLogs($log, $alog, $ngf, $vpp);
        
        // generate the polynomial coefficients (c)
        $plc = array_fill(0, ($ncc + 1), 0);
        $plc[0] = 1;
        for ($i = 1; $i <= $ncc; ++$i) {
            $plc[$i] = $plc[($i-1)];
            for ($j = ($i - 1); $j >= 1; --$j) {
                $plc[$j] = $plc[($j - 1)] ^ $this->getGFProduct($plc[$j], $alog[$i], $log, $alog, $ngf);
            }
            $plc[0] = $this->getGFProduct($plc[0], $alog[$i], $log, $alog, $ngf);
        }
        ksort($plc);
        
        // total number of data codewords
        $num_wd = ($nbk * $ncw);
        // total number of error codewords
        $num_we = ($nbk * $ncc);
        // for each block
        for ($b = 0; $b < $nbk; ++$b) {
            // create interleaved data block
            $block = array();
            for ($n = $b; $n < $num_wd; $n += $nbk) {
                $block[] = $wdc[$n];
            }
            // initialize error codewords
            $wec = array_fill(0, ($ncc + 1), 0);
            // calculate error correction codewords for this block
            for ($i = 0; $i < $ncw; ++$i) {
                $ker = ($wec[0] ^ $block[$i]);
                for ($j = 0; $j < $ncc; ++$j) {
                    $wec[$j] = ($wec[($j + 1)] ^ $this->getGFProduct($ker, $plc[($ncc - $j - 1)], $log, $alog, $ngf));
                }
            }
            // add error codewords at the end of data codewords
            $j = 0;
            for ($i = $b; $i < $num_we; $i += $nbk) {
                $wdc[($num_wd + $i)] = $wec[$j];
                ++$j;
            }
        }
        // reorder codewords
        ksort($wdc);
        return $wdc;
    }

    /**
     * Generate the log ($log) and antilog ($alog) tables
     *
     * @param array $log  Log table
     * @param arrya $alog Anti-Log table
     * @param int   $ngf  Number of fields on log/antilog table (power of 2).
     * @param int   $vpp  The value of its prime modulus polynomial (301 for ECC200).
     */
    protected function genLogs(&$log, &$alog, $ngf, $vpp)
    {
        for ($i = 1; $i < $ngf; ++$i) {
            $alog[$i] = ($alog[($i - 1)] * 2);
            if ($alog[$i] >= $ngf) {
                $alog[$i] ^= $vpp;
            }
            $log[$alog[$i]] = $i;
        }
        ksort($log);
    }
}
Modes.php
wget 'https://lists2.roe3.org/hesk/inc/tecnick/Barcode/Type/Square/Datamatrix/Modes.php'
View Content
<?php
/**
 * Modes.php
 *
 * @since       2015-02-21
 * @category    Library
 * @package     Barcode
 * @author      Nicola Asuni <info@tecnick.com>
 * @copyright   2010-2016 Nicola Asuni - Tecnick.com LTD
 * @license     http://www.gnu.org/copyleft/lesser.html GNU-LGPL v3 (see LICENSE.TXT)
 * @link        https://github.com/tecnickcom/tc-lib-barcode
 *
 * This file is part of tc-lib-barcode software library.
 */

namespace Com\Tecnick\Barcode\Type\Square\Datamatrix;

use \Com\Tecnick\Barcode\Exception as BarcodeException;

/**
 * Com\Tecnick\Barcode\Type\Square\Datamatrix\Modes
 *
 * Modes for Datamatrix Barcode type class
 *
 * @since       2015-02-21
 * @category    Library
 * @package     Barcode
 * @author      Nicola Asuni <info@tecnick.com>
 * @copyright   2010-2016 Nicola Asuni - Tecnick.com LTD
 * @license     http://www.gnu.org/copyleft/lesser.html GNU-LGPL v3 (see LICENSE.TXT)
 * @link        https://github.com/tecnickcom/tc-lib-barcode
 */
abstract class Modes extends \Com\Tecnick\Barcode\Type\Square\Datamatrix\Placement
{
    /**
     * Return the 253-state codeword
     *
     * @param int $cdwpad Pad codeword.
     * @param int $cdwpos Number of data codewords from the beginning of encoded data.
     *
     * @return pad codeword
     */
    public function get253StateCodeword($cdwpad, $cdwpos)
    {
        $pad = ($cdwpad + (((149 * $cdwpos) % 253) + 1));
        if ($pad > 254) {
            $pad -= 254;
        }
        return $pad;
    }

    /**
     * Return the 255-state codeword
     *
     * @param int $cdwpad Pad codeword.
     * @param int $cdwpos Number of data codewords from the beginning of encoded data.
     *
     * @return int pad codeword
     */
    protected function get255StateCodeword($cdwpad, $cdwpos)
    {
        $pad = ($cdwpad + (((149 * $cdwpos) % 255) + 1));
        if ($pad > 255) {
            $pad -= 256;
        }
        return $pad;
    }

    /**
     * Returns true if the char belongs to the selected mode
     *
     * @param int $chr  Character (byte) to check.
     * @param int $mode Current encoding mode.
     *
     * @return boolean true if the char is of the selected mode.
     */
    protected function isCharMode($chr, $mode)
    {
        $map = array(
            //Data::ENC_ASCII     => 'isASCIIMode',
            Data::ENC_C40       => 'isC40Mode',
            Data::ENC_TXT       => 'isTXTMode',
            Data::ENC_X12       => 'isX12Mode',
            Data::ENC_EDF       => 'isEDFMode',
            Data::ENC_BASE256   => 'isBASE256Mode',
            Data::ENC_ASCII_EXT => 'isASCIIEXTMode',
            Data::ENC_ASCII_NUM => 'isASCIINUMMode'
        );
        $method = $map[$mode];
        return $this->$method($chr);
    }

    ///**
    // * Tell if char is ASCII character 0 to 127
    // *
    // * @param int $chr  Character (byte) to check.
    // *
    // * @return boolean
    // */
    //protected function isASCIIMode($chr)
    //{
    //    return (($chr >= 0) && ($chr <= 127));
    //}

    /**
     * Tell if char is Upper-case alphanumeric
     *
     * @param int $chr  Character (byte) to check.
     *
     * @return boolean
     */
    protected function isC40Mode($chr)
    {
        return (($chr == 32) || (($chr >= 48) && ($chr <= 57)) || (($chr >= 65) && ($chr <= 90)));
    }

    /**
     * Tell if char is Lower-case alphanumeric
     *
     * @param int $chr  Character (byte) to check.
     *
     * @return boolean
     */
    protected function isTXTMode($chr)
    {
        return (($chr == 32) || (($chr >= 48) && ($chr <= 57)) || (($chr >= 97) && ($chr <= 122)));
    }

    /**
     * Tell if char is ANSI X12
     *
     * @param int $chr  Character (byte) to check.
     *
     * @return boolean
     */
    protected function isX12Mode($chr)
    {
        return (($chr == 13) || ($chr == 42) || ($chr == 62));
    }

    /**
     * Tell if char is ASCII character 32 to 94
     *
     * @param int $chr  Character (byte) to check.
     *
     * @return boolean
     */
    protected function isEDFMode($chr)
    {
        return (($chr >= 32) && ($chr <= 94));
    }

    /**
     * Tell if char is Function character (FNC1, Structured Append, Reader Program, or Code Page)
     *
     * @param int $chr  Character (byte) to check.
     *
     * @return boolean
     */
    protected function isBASE256Mode($chr)
    {
        return (($chr == 232) || ($chr == 233) || ($chr == 234) || ($chr == 241));
    }

    /**
     * Tell if char is ASCII character 128 to 255
     *
     * @param int $chr  Character (byte) to check.
     *
     * @return boolean
     */
    protected function isASCIIEXTMode($chr)
    {
        return (($chr >= 128) && ($chr <= 255));
    }

    /**
     * Tell if char is ASCII digits
     *
     * @param int $chr  Character (byte) to check.
     *
     * @return boolean
     */
    protected function isASCIINUMMode($chr)
    {
        return (($chr >= 48) && ($chr <= 57));
    }

    /**
     * Choose the minimum matrix size and return the max number of data codewords.
     *
     * @param int $numcw Number of current codewords.
     *
     * @return number of data codewords in matrix
     */
    protected function getMaxDataCodewords($numcw)
    {
        $mdc = 0;
        foreach (Data::$symbattr[$this->shape] as $matrix) {
            if ($matrix[11] >= $numcw) {
                $mdc = $matrix[11];
                break;
            }
        }
        return $mdc;
    }

    /**
     * Get the switching codeword to a new encoding mode (latch codeword)
     * @param $mode (int) New encoding mode.
     * @return (int) Switch codeword.
     * @protected
     */
    protected function getSwitchEncodingCodeword($mode)
    {
        $map = array(
            Data::ENC_ASCII   => 254,
            Data::ENC_C40     => 230,
            Data::ENC_TXT     => 239,
            Data::ENC_X12     => 238,
            Data::ENC_EDF     => 240,
            Data::ENC_BASE256 => 231
        );
        $cdw = $map[$mode];
        if (($cdw == 254) && ($this->last_enc == Data::ENC_EDF)) {
            $cdw = 124;
        }
        return $cdw;
    }
}
Placement.php
wget 'https://lists2.roe3.org/hesk/inc/tecnick/Barcode/Type/Square/Datamatrix/Placement.php'
View Content
<?php
/**
 * Placement.php
 *
 * @since       2015-02-21
 * @category    Library
 * @package     Barcode
 * @author      Nicola Asuni <info@tecnick.com>
 * @copyright   2010-2016 Nicola Asuni - Tecnick.com LTD
 * @license     http://www.gnu.org/copyleft/lesser.html GNU-LGPL v3 (see LICENSE.TXT)
 * @link        https://github.com/tecnickcom/tc-lib-barcode
 *
 * This file is part of tc-lib-barcode software library.
 */

namespace Com\Tecnick\Barcode\Type\Square\Datamatrix;

use \Com\Tecnick\Barcode\Exception as BarcodeException;

/**
 * Com\Tecnick\Barcode\Type\Square\Datamatrix\Placement
 *
 * Placement methods for Datamatrix Barcode type class
 *
 * @since       2015-02-21
 * @category    Library
 * @package     Barcode
 * @author      Nicola Asuni <info@tecnick.com>
 * @copyright   2010-2016 Nicola Asuni - Tecnick.com LTD
 * @license     http://www.gnu.org/copyleft/lesser.html GNU-LGPL v3 (see LICENSE.TXT)
 * @link        https://github.com/tecnickcom/tc-lib-barcode
 */
abstract class Placement
{
    /**
     * Places "chr+bit" with appropriate wrapping within array[].
     * (Annex F - ECC 200 symbol character placement)
     *
     * @param array $marr  Array of symbols.
     * @param int   $nrow  Number of rows.
     * @param int   $ncol  Number of columns.
     * @param int   $row   Row number.
     * @param int   $col   Column number.
     * @param int   $chr   Char byte.
     * @param int   $bit   Bit.
     *
     * @return array
     */
    protected function placeModule($marr, $nrow, $ncol, $row, $col, $chr, $bit)
    {
        if ($row < 0) {
            $row += $nrow;
            $col += (4 - (($nrow + 4) % 8));
        }
        if ($col < 0) {
            $col += $ncol;
            $row += (4 - (($ncol + 4) % 8));
        }
        $marr[(($row * $ncol) + $col)] = ((10 * $chr) + $bit);
        return $marr;
    }

    /**
     * Places the 8 bits of a utah-shaped symbol character.
     * (Annex F - ECC 200 symbol character placement)
     *
     * @param array $marr  Array of symbols.
     * @param int   $nrow  Number of rows.
     * @param int   $ncol  Number of columns.
     * @param int   $row   Row number.
     * @param int   $col   Column number.
     * @param int   $chr   Char byte.
     *
     * @return array
     */
    protected function placeUtah($marr, $nrow, $ncol, $row, $col, $chr)
    {
        $marr = $this->placeModule($marr, $nrow, $ncol, $row-2, $col-2, $chr, 1);
        $marr = $this->placeModule($marr, $nrow, $ncol, $row-2, $col-1, $chr, 2);
        $marr = $this->placeModule($marr, $nrow, $ncol, $row-1, $col-2, $chr, 3);
        $marr = $this->placeModule($marr, $nrow, $ncol, $row-1, $col-1, $chr, 4);
        $marr = $this->placeModule($marr, $nrow, $ncol, $row-1, $col, $chr, 5);
        $marr = $this->placeModule($marr, $nrow, $ncol, $row, $col-2, $chr, 6);
        $marr = $this->placeModule($marr, $nrow, $ncol, $row, $col-1, $chr, 7);
        $marr = $this->placeModule($marr, $nrow, $ncol, $row, $col, $chr, 8);
        return $marr;
    }

    /**
     * Places the 8 bits of the first special corner case.
     * (Annex F - ECC 200 symbol character placement)
     *
     * @param array $marr  Array of symbols
     * @param int   $nrow  Number of rows
     * @param int   $ncol  Number of columns
     * @param int   $chr   Char byte
     * @param int   $row   Current row
     * @param int   $col   Current column
     *
     * @return array
     */
    protected function placeCornerA($marr, $nrow, $ncol, &$chr, $row, $col)
    {
        if (($row != $nrow) || ($col != 0)) {
            return $marr;
        }
        $marr = $this->placeModule($marr, $nrow, $ncol, $nrow-1, 0, $chr, 1);
        $marr = $this->placeModule($marr, $nrow, $ncol, $nrow-1, 1, $chr, 2);
        $marr = $this->placeModule($marr, $nrow, $ncol, $nrow-1, 2, $chr, 3);
        $marr = $this->placeModule($marr, $nrow, $ncol, 0, $ncol-2, $chr, 4);
        $marr = $this->placeModule($marr, $nrow, $ncol, 0, $ncol-1, $chr, 5);
        $marr = $this->placeModule($marr, $nrow, $ncol, 1, $ncol-1, $chr, 6);
        $marr = $this->placeModule($marr, $nrow, $ncol, 2, $ncol-1, $chr, 7);
        $marr = $this->placeModule($marr, $nrow, $ncol, 3, $ncol-1, $chr, 8);
        ++$chr;
        return $marr;
    }

    /**
     * Places the 8 bits of the second special corner case.
     * (Annex F - ECC 200 symbol character placement)
     *
     * @param array $marr  Array of symbols
     * @param int   $nrow  Number of rows
     * @param int   $ncol  Number of columns
     * @param int   $chr   Char byte
     * @param int   $row   Current row
     * @param int   $col   Current column
     *
     * @return array
     */
    protected function placeCornerB($marr, $nrow, $ncol, &$chr, $row, $col)
    {
        if (($row != ($nrow - 2)) || ($col != 0) || (($ncol % 4) == 0)) {
            return $marr;
        }
        $marr = $this->placeModule($marr, $nrow, $ncol, $nrow-3, 0, $chr, 1);
        $marr = $this->placeModule($marr, $nrow, $ncol, $nrow-2, 0, $chr, 2);
        $marr = $this->placeModule($marr, $nrow, $ncol, $nrow-1, 0, $chr, 3);
        $marr = $this->placeModule($marr, $nrow, $ncol, 0, $ncol-4, $chr, 4);
        $marr = $this->placeModule($marr, $nrow, $ncol, 0, $ncol-3, $chr, 5);
        $marr = $this->placeModule($marr, $nrow, $ncol, 0, $ncol-2, $chr, 6);
        $marr = $this->placeModule($marr, $nrow, $ncol, 0, $ncol-1, $chr, 7);
        $marr = $this->placeModule($marr, $nrow, $ncol, 1, $ncol-1, $chr, 8);
        ++$chr;
        return $marr;
    }

    /**
     * Places the 8 bits of the third special corner case.
     * (Annex F - ECC 200 symbol character placement)
     *
     * @param array $marr  Array of symbols
     * @param int   $nrow  Number of rows
     * @param int   $ncol  Number of columns
     * @param int   $chr   Char byte
     * @param int   $row   Current row
     * @param int   $col   Current column
     *
     * @return array
     */
    protected function placeCornerC($marr, $nrow, $ncol, &$chr, $row, $col)
    {
        if (($row != ($nrow - 2)) || ($col != 0) || (($ncol % 8) != 4)) {
            return $marr;
        }
        $marr = $this->placeModule($marr, $nrow, $ncol, $nrow-3, 0, $chr, 1);
        $marr = $this->placeModule($marr, $nrow, $ncol, $nrow-2, 0, $chr, 2);
        $marr = $this->placeModule($marr, $nrow, $ncol, $nrow-1, 0, $chr, 3);
        $marr = $this->placeModule($marr, $nrow, $ncol, 0, $ncol-2, $chr, 4);
        $marr = $this->placeModule($marr, $nrow, $ncol, 0, $ncol-1, $chr, 5);
        $marr = $this->placeModule($marr, $nrow, $ncol, 1, $ncol-1, $chr, 6);
        $marr = $this->placeModule($marr, $nrow, $ncol, 2, $ncol-1, $chr, 7);
        $marr = $this->placeModule($marr, $nrow, $ncol, 3, $ncol-1, $chr, 8);
        ++$chr;
        return $marr;
    }

    /**
     * Places the 8 bits of the fourth special corner case.
     * (Annex F - ECC 200 symbol character placement)
     *
     * @param array $marr  Array of symbols
     * @param int   $nrow  Number of rows
     * @param int   $ncol  Number of columns
     * @param int   $chr   Char byte
     * @param int   $row   Current row
     * @param int   $col   Current column
     *
     * @return array
     */
    protected function placeCornerD($marr, $nrow, $ncol, &$chr, $row, $col)
    {
        if (($row != ($nrow + 4)) || ($col != 2) || ($ncol % 8)) {
            return $marr;
        }
        $marr = $this->placeModule($marr, $nrow, $ncol, $nrow-1, 0, $chr, 1);
        $marr = $this->placeModule($marr, $nrow, $ncol, $nrow-1, $ncol-1, $chr, 2);
        $marr = $this->placeModule($marr, $nrow, $ncol, 0, $ncol-3, $chr, 3);
        $marr = $this->placeModule($marr, $nrow, $ncol, 0, $ncol-2, $chr, 4);
        $marr = $this->placeModule($marr, $nrow, $ncol, 0, $ncol-1, $chr, 5);
        $marr = $this->placeModule($marr, $nrow, $ncol, 1, $ncol-3, $chr, 6);
        $marr = $this->placeModule($marr, $nrow, $ncol, 1, $ncol-2, $chr, 7);
        $marr = $this->placeModule($marr, $nrow, $ncol, 1, $ncol-1, $chr, 8);
        ++$chr;
        return $marr;
    }

    

    /**
     * Sweep upward diagonally, inserting successive characters,
     * (Annex F - ECC 200 symbol character placement)
     *
     * @param array $marr  Array of symbols
     * @param int   $nrow  Number of rows
     * @param int   $ncol  Number of columns
     * @param int   $chr   Char byte
     * @param int   $row   Current row
     * @param int   $col   Current column
     *
     * @return array
     */
    protected function placeSweepUpward($marr, $nrow, $ncol, &$chr, &$row, &$col)
    {
        do {
            if (($row < $nrow) && ($col >= 0) && (!$marr[(($row * $ncol) + $col)])) {
                $marr = $this->placeUtah($marr, $nrow, $ncol, $row, $col, $chr);
                ++$chr;
            }
            $row -= 2;
            $col += 2;
        } while (($row >= 0) && ($col < $ncol));
        ++$row;
        $col += 3;
        return $marr;
    }

    /**
     * Sweep downward diagonally, inserting successive characters,
     * (Annex F - ECC 200 symbol character placement)
     *
     * @param array $marr  Array of symbols
     * @param int   $nrow  Number of rows
     * @param int   $ncol  Number of columns
     * @param int   $chr   Char byte
     * @param int   $row   Current row
     * @param int   $col   Current column
     *
     * @return array
     */
    protected function placeSweepDownward($marr, $nrow, $ncol, &$chr, &$row, &$col)
    {
        do {
            if (($row >= 0) && ($col < $ncol) && (!$marr[(($row * $ncol) + $col)])) {
                $marr = $this->placeUtah($marr, $nrow, $ncol, $row, $col, $chr);
                ++$chr;
            }
            $row += 2;
            $col -= 2;
        } while (($row < $nrow) && ($col >= 0));
        $row += 3;
        ++$col;
        return $marr;
    }

    /**
     * Build a placement map.
     * (Annex F - ECC 200 symbol character placement)
     *
     * @param int $nrow  Number of rows.
     * @param int $ncol  Number of columns.
     *
     * @return array
     */
    public function getPlacementMap($nrow, $ncol)
    {
        // initialize array with zeros
        $marr = array_fill(0, ($nrow * $ncol), 0);
        // set starting values
        $chr = 1;
        $row = 4;
        $col = 0;
        do {
            // repeatedly first check for one of the special corner cases, then
            $marr = $this->placeCornerA($marr, $nrow, $ncol, $chr, $row, $col);
            $marr = $this->placeCornerB($marr, $nrow, $ncol, $chr, $row, $col);
            $marr = $this->placeCornerC($marr, $nrow, $ncol, $chr, $row, $col);
            $marr = $this->placeCornerD($marr, $nrow, $ncol, $chr, $row, $col);
            // sweep upward diagonally, inserting successive characters,
            $marr = $this->placeSweepUpward($marr, $nrow, $ncol, $chr, $row, $col);
            // & then sweep downward diagonally, inserting successive characters,...
            $marr = $this->placeSweepDownward($marr, $nrow, $ncol, $chr, $row, $col);
            // ... until the entire array is scanned
        } while (($row < $nrow) || ($col < $ncol));
        // lastly, if the lower righthand corner is untouched, fill in fixed pattern
        if (!$marr[(($nrow * $ncol) - 1)]) {
            $marr[(($nrow * $ncol) - 1)] = 1;
            $marr[(($nrow * $ncol) - $ncol - 2)] = 1;
        }
        return $marr;
    }
}
Steps.php
wget 'https://lists2.roe3.org/hesk/inc/tecnick/Barcode/Type/Square/Datamatrix/Steps.php'
View Content
<?php
/**
 * Steps.php
 *
 * @since       2015-02-21
 * @category    Library
 * @package     Barcode
 * @author      Nicola Asuni <info@tecnick.com>
 * @copyright   2015-2016 Nicola Asuni - Tecnick.com LTD
 * @license     http://www.gnu.org/copyleft/lesser.html GNU-LGPL v3 (see LICENSE.TXT)
 * @link        https://github.com/tecnickcom/tc-lib-barcode
 *
 * This file is part of tc-lib-barcode software library.
 */

namespace Com\Tecnick\Barcode\Type\Square\Datamatrix;

use \Com\Tecnick\Barcode\Exception as BarcodeException;
use \Com\Tecnick\Barcode\Type\Square\Datamatrix\Data;

/**
 * Com\Tecnick\Barcode\Type\Square\Datamatrix\Steps
 *
 * Steps methods for Datamatrix Barcode type class
 *
 * @since       2015-02-21
 * @category    Library
 * @package     Barcode
 * @author      Nicola Asuni <info@tecnick.com>
 * @copyright   2015-2016 Nicola Asuni - Tecnick.com LTD
 * @license     http://www.gnu.org/copyleft/lesser.html GNU-LGPL v3 (see LICENSE.TXT)
 * @link        https://github.com/tecnickcom/tc-lib-barcode
 */
abstract class Steps extends \Com\Tecnick\Barcode\Type\Square\Datamatrix\Modes
{
    /**
     * The look-ahead test scans the data to be encoded to find the best mode (Annex P - steps from J to S).
     *
     * @param string $data Data to encode
     * @param int    $pos  Current position
     * @param int    $mode Current encoding mode
     *
     * @return int encoding mode
     */
    public function lookAheadTest($data, $pos, $mode)
    {
        $data_length = strlen($data);
        if ($pos >= $data_length) {
            return $mode;
        }
        $charscount = 0; // count processed chars
        // STEP J
        if ($mode == Data::ENC_ASCII) {
            $numch = array(0, 1, 1, 1, 1, 1.25);
        } else {
            $numch = array(1, 2, 2, 2, 2, 2.25);
            $numch[$mode] = 0;
        }
        while (true) {
            if (($pos + $charscount) == $data_length) {
                return $this->stepK($numch);
            }
            $chr = ord($data[$pos + $charscount]);
            $charscount++;
            $this->stepL($chr, $numch);
            $this->stepM($chr, $numch);
            $this->stepN($chr, $numch);
            $this->stepO($chr, $numch);
            $this->stepP($chr, $numch);
            $this->stepQ($chr, $numch);
            if ($charscount >= 4) {
                $ret = $this->stepR($numch, $pos, $data_length, $charscount, $data);
                if ($ret !== null) {
                    return $ret;
                }
            }
        }
        throw new BarcodeException('LookAhead Error');
    }

    /**
     * Step K
     *
     * @param int $numch
     *
     * @return int
     */
    protected function stepK($numch)
    {
        if ($numch[Data::ENC_ASCII] <= ceil(min(
            $numch[Data::ENC_C40],
            $numch[Data::ENC_TXT],
            $numch[Data::ENC_X12],
            $numch[Data::ENC_EDF],
            $numch[Data::ENC_BASE256]
        ))) {
            return Data::ENC_ASCII;
        }
        if ($numch[Data::ENC_BASE256] < ceil(min(
            $numch[Data::ENC_ASCII],
            $numch[Data::ENC_C40],
            $numch[Data::ENC_TXT],
            $numch[Data::ENC_X12],
            $numch[Data::ENC_EDF]
        ))) {
            return Data::ENC_BASE256;
        }
        if ($numch[Data::ENC_EDF] < ceil(min(
            $numch[Data::ENC_ASCII],
            $numch[Data::ENC_C40],
            $numch[Data::ENC_TXT],
            $numch[Data::ENC_X12],
            $numch[Data::ENC_BASE256]
        ))) {
            return Data::ENC_EDF;
        }
        if ($numch[Data::ENC_TXT] < ceil(min(
            $numch[Data::ENC_ASCII],
            $numch[Data::ENC_C40],
            $numch[Data::ENC_X12],
            $numch[Data::ENC_EDF],
            $numch[Data::ENC_BASE256]
        ))) {
            return Data::ENC_TXT;
        }
        if ($numch[Data::ENC_X12] < ceil(min(
            $numch[Data::ENC_ASCII],
            $numch[Data::ENC_C40],
            $numch[Data::ENC_TXT],
            $numch[Data::ENC_EDF],
            $numch[Data::ENC_BASE256]
        ))) {
            return Data::ENC_X12;
        }
        return Data::ENC_C40;
    }

    /**
     * Step L
     *
     * @param int $chr
     * @param int $numch
     */
    protected function stepL($chr, &$numch)
    {
        if ($this->isCharMode($chr, Data::ENC_ASCII_NUM)) {
            $numch[Data::ENC_ASCII] += (1 / 2);
        } elseif ($this->isCharMode($chr, Data::ENC_ASCII_EXT)) {
            $numch[Data::ENC_ASCII] = ceil($numch[Data::ENC_ASCII]);
            $numch[Data::ENC_ASCII] += 2;
        } else {
            $numch[Data::ENC_ASCII] = ceil($numch[Data::ENC_ASCII]);
            $numch[Data::ENC_ASCII] += 1;
        }
    }

    /**
     * Step M
     *
     * @param int $chr
     * @param int $numch
     */
    protected function stepM($chr, &$numch)
    {
        if ($this->isCharMode($chr, Data::ENC_C40)) {
            $numch[Data::ENC_C40] += (2 / 3);
        } elseif ($this->isCharMode($chr, Data::ENC_ASCII_EXT)) {
            $numch[Data::ENC_C40] += (8 / 3);
        } else {
            $numch[Data::ENC_C40] += (4 / 3);
        }
    }

    /**
     * Step N
     *
     * @param int $chr
     * @param int $numch
     */
    protected function stepN($chr, &$numch)
    {
        if ($this->isCharMode($chr, Data::ENC_TXT)) {
            $numch[Data::ENC_TXT] += (2 / 3);
        } elseif ($this->isCharMode($chr, Data::ENC_ASCII_EXT)) {
            $numch[Data::ENC_TXT] += (8 / 3);
        } else {
            $numch[Data::ENC_TXT] += (4 / 3);
        }
    }

    /**
     * Step O
     *
     * @param int $chr
     * @param int $numch
     */
    protected function stepO($chr, &$numch)
    {
        if ($this->isCharMode($chr, Data::ENC_X12) || $this->isCharMode($chr, Data::ENC_C40)) {
            $numch[Data::ENC_X12] += (2 / 3);
        } elseif ($this->isCharMode($chr, Data::ENC_ASCII_EXT)) {
            $numch[Data::ENC_X12] += (13 / 3);
        } else {
            $numch[Data::ENC_X12] += (10 / 3);
        }
    }

    /**
     * Step P
     *
     * @param int $chr
     * @param int $numch
     */
    protected function stepP($chr, &$numch)
    {
        if ($this->isCharMode($chr, Data::ENC_EDF)) {
            $numch[Data::ENC_EDF] += (3 / 4);
        } elseif ($this->isCharMode($chr, Data::ENC_ASCII_EXT)) {
            $numch[Data::ENC_EDF] += (17 / 4);
        } else {
            $numch[Data::ENC_EDF] += (13 / 4);
        }
    }

    /**
     * Step Q
     *
     * @param int $chr
     * @param int $numch
     */
    protected function stepQ($chr, &$numch)
    {
        if ($this->isCharMode($chr, Data::ENC_BASE256)) {
            $numch[Data::ENC_BASE256] += 4;
        } else {
            $numch[Data::ENC_BASE256] += 1;
        }
    }

    /**
     * Step R-f
     *
     * @param int    $numch
     * @param int    $pos
     * @param int    $data_length
     * @param int    $charscount
     * @param string $data
     *
     * @return int   Encoding mode
     */
    protected function stepRf($numch, $pos, $data_length, $charscount, $data)
    {
        if (($numch[Data::ENC_C40] + 1) < min(
            $numch[Data::ENC_ASCII],
            $numch[Data::ENC_TXT],
            $numch[Data::ENC_EDF],
            $numch[Data::ENC_BASE256]
        )) {
            if ($numch[Data::ENC_C40] < $numch[Data::ENC_X12]) {
                return Data::ENC_C40;
            }
            if ($numch[Data::ENC_C40] == $numch[Data::ENC_X12]) {
                $ker = ($pos + $charscount + 1);
                while ($ker < $data_length) {
                    $tmpchr = ord($data[$ker]);
                    if ($this->isCharMode($tmpchr, Data::ENC_X12)) {
                        return Data::ENC_X12;
                    } elseif (!($this->isCharMode($tmpchr, Data::ENC_X12)
                        || $this->isCharMode($tmpchr, Data::ENC_C40))) {
                        break;
                    }
                    ++$ker;
                }
                return Data::ENC_C40;
            }
        }
        return null;
    }

    /**
     * Step R
     *
     * @param int    $numch
     * @param int    $pos
     * @param int    $data_length
     * @param int    $charscount
     * @param string $data
     */
    protected function stepR($numch, $pos, $data_length, $charscount, $data)
    {
        if (($numch[Data::ENC_ASCII] + 1) <= min(
            $numch[Data::ENC_C40],
            $numch[Data::ENC_TXT],
            $numch[Data::ENC_X12],
            $numch[Data::ENC_EDF],
            $numch[Data::ENC_BASE256]
        )) {
            return Data::ENC_ASCII;
        }
        if ((($numch[Data::ENC_BASE256] + 1) <= $numch[Data::ENC_ASCII])
            || (($numch[Data::ENC_BASE256] + 1) < min(
                $numch[Data::ENC_C40],
                $numch[Data::ENC_TXT],
                $numch[Data::ENC_X12],
                $numch[Data::ENC_EDF]
            ))) {
            return Data::ENC_BASE256;
        }
        if (($numch[Data::ENC_EDF] + 1) < min(
            $numch[Data::ENC_ASCII],
            $numch[Data::ENC_C40],
            $numch[Data::ENC_TXT],
            $numch[Data::ENC_X12],
            $numch[Data::ENC_BASE256]
        )) {
            return Data::ENC_EDF;
        }
        if (($numch[Data::ENC_TXT] + 1) < min(
            $numch[Data::ENC_ASCII],
            $numch[Data::ENC_C40],
            $numch[Data::ENC_X12],
            $numch[Data::ENC_EDF],
            $numch[Data::ENC_BASE256]
        )) {
            return Data::ENC_TXT;
        }
        if (($numch[Data::ENC_X12] + 1) < min(
            $numch[Data::ENC_ASCII],
            $numch[Data::ENC_C40],
            $numch[Data::ENC_TXT],
            $numch[Data::ENC_EDF],
            $numch[Data::ENC_BASE256]
        )) {
            return Data::ENC_X12;
        }
        return $this->stepRf($numch, $pos, $data_length, $charscount, $data);
    }
}