Home | History | Annotate | Download | only in datamatrix
      1 // Copyright 2014 PDFium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
      6 // Original code is licensed as follows:
      7 /*
      8  * Copyright 2006 Jeremias Maerki
      9  *
     10  * Licensed under the Apache License, Version 2.0 (the "License");
     11  * you may not use this file except in compliance with the License.
     12  * You may obtain a copy of the License at
     13  *
     14  *      http://www.apache.org/licenses/LICENSE-2.0
     15  *
     16  * Unless required by applicable law or agreed to in writing, software
     17  * distributed under the License is distributed on an "AS IS" BASIS,
     18  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     19  * See the License for the specific language governing permissions and
     20  * limitations under the License.
     21  */
     22 
     23 #include "xfa/fxbarcode/datamatrix/BC_SymbolInfo.h"
     24 
     25 #include "xfa/fxbarcode/BC_Dimension.h"
     26 #include "xfa/fxbarcode/common/BC_CommonBitMatrix.h"
     27 #include "xfa/fxbarcode/datamatrix/BC_DataMatrixSymbolInfo144.h"
     28 #include "xfa/fxbarcode/datamatrix/BC_Encoder.h"
     29 #include "xfa/fxbarcode/datamatrix/BC_SymbolShapeHint.h"
     30 
     31 namespace {
     32 
     33 const size_t kSymbolsCount = 30;
     34 
     35 CBC_SymbolInfo* g_symbols[kSymbolsCount] = {
     36     nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
     37     nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
     38     nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
     39     nullptr, nullptr, nullptr, nullptr, nullptr, nullptr};
     40 
     41 }  // namespace
     42 
     43 void CBC_SymbolInfo::Initialize() {
     44   g_symbols[0] = new CBC_SymbolInfo(false, 3, 5, 8, 8, 1);
     45   g_symbols[1] = new CBC_SymbolInfo(false, 5, 7, 10, 10, 1);
     46   g_symbols[2] = new CBC_SymbolInfo(true, 5, 7, 16, 6, 1);
     47   g_symbols[3] = new CBC_SymbolInfo(false, 8, 10, 12, 12, 1);
     48   g_symbols[4] = new CBC_SymbolInfo(true, 10, 11, 14, 6, 2);
     49   g_symbols[5] = new CBC_SymbolInfo(false, 12, 12, 14, 14, 1);
     50   g_symbols[6] = new CBC_SymbolInfo(true, 16, 14, 24, 10, 1);
     51   g_symbols[7] = new CBC_SymbolInfo(false, 18, 14, 16, 16, 1);
     52   g_symbols[8] = new CBC_SymbolInfo(false, 22, 18, 18, 18, 1);
     53   g_symbols[9] = new CBC_SymbolInfo(true, 22, 18, 16, 10, 2);
     54   g_symbols[10] = new CBC_SymbolInfo(false, 30, 20, 20, 20, 1);
     55   g_symbols[11] = new CBC_SymbolInfo(true, 32, 24, 16, 14, 2);
     56   g_symbols[12] = new CBC_SymbolInfo(false, 36, 24, 22, 22, 1);
     57   g_symbols[13] = new CBC_SymbolInfo(false, 44, 28, 24, 24, 1);
     58   g_symbols[14] = new CBC_SymbolInfo(true, 49, 28, 22, 14, 2);
     59   g_symbols[15] = new CBC_SymbolInfo(false, 62, 36, 14, 14, 4);
     60   g_symbols[16] = new CBC_SymbolInfo(false, 86, 42, 16, 16, 4);
     61   g_symbols[17] = new CBC_SymbolInfo(false, 114, 48, 18, 18, 4);
     62   g_symbols[18] = new CBC_SymbolInfo(false, 144, 56, 20, 20, 4);
     63   g_symbols[19] = new CBC_SymbolInfo(false, 174, 68, 22, 22, 4);
     64   g_symbols[20] = new CBC_SymbolInfo(false, 204, 84, 24, 24, 4, 102, 42);
     65   g_symbols[21] = new CBC_SymbolInfo(false, 280, 112, 14, 14, 16, 140, 56);
     66   g_symbols[22] = new CBC_SymbolInfo(false, 368, 144, 16, 16, 16, 92, 36);
     67   g_symbols[23] = new CBC_SymbolInfo(false, 456, 192, 18, 18, 16, 114, 48);
     68   g_symbols[24] = new CBC_SymbolInfo(false, 576, 224, 20, 20, 16, 144, 56);
     69   g_symbols[25] = new CBC_SymbolInfo(false, 696, 272, 22, 22, 16, 174, 68);
     70   g_symbols[26] = new CBC_SymbolInfo(false, 816, 336, 24, 24, 16, 136, 56);
     71   g_symbols[27] = new CBC_SymbolInfo(false, 1050, 408, 18, 18, 36, 175, 68);
     72   g_symbols[28] = new CBC_SymbolInfo(false, 1304, 496, 20, 20, 36, 163, 62);
     73   g_symbols[29] = new CBC_DataMatrixSymbolInfo144();
     74 }
     75 
     76 void CBC_SymbolInfo::Finalize() {
     77   for (size_t i = 0; i < kSymbolsCount; i++) {
     78     delete g_symbols[i];
     79     g_symbols[i] = nullptr;
     80   }
     81 }
     82 
     83 CBC_SymbolInfo::CBC_SymbolInfo(bool rectangular,
     84                                int32_t dataCapacity,
     85                                int32_t errorCodewords,
     86                                int32_t matrixWidth,
     87                                int32_t matrixHeight,
     88                                int32_t dataRegions) {
     89   m_rectangular = rectangular;
     90   m_dataCapacity = dataCapacity;
     91   m_errorCodewords = errorCodewords;
     92   m_matrixWidth = matrixWidth;
     93   m_matrixHeight = matrixHeight;
     94   m_dataRegions = dataRegions;
     95   m_rsBlockData = dataCapacity;
     96   m_rsBlockError = errorCodewords;
     97 }
     98 CBC_SymbolInfo::CBC_SymbolInfo(bool rectangular,
     99                                int32_t dataCapacity,
    100                                int32_t errorCodewords,
    101                                int32_t matrixWidth,
    102                                int32_t matrixHeight,
    103                                int32_t dataRegions,
    104                                int32_t rsBlockData,
    105                                int32_t rsBlockError) {
    106   m_rectangular = rectangular;
    107   m_dataCapacity = dataCapacity;
    108   m_errorCodewords = errorCodewords;
    109   m_matrixWidth = matrixWidth;
    110   m_matrixHeight = matrixHeight;
    111   m_dataRegions = dataRegions;
    112   m_rsBlockData = rsBlockData;
    113   m_rsBlockError = rsBlockError;
    114 }
    115 CBC_SymbolInfo::~CBC_SymbolInfo() {}
    116 
    117 CBC_SymbolInfo* CBC_SymbolInfo::lookup(int32_t dataCodewords, int32_t& e) {
    118   return lookup(dataCodewords, FORCE_NONE, true, e);
    119 }
    120 CBC_SymbolInfo* CBC_SymbolInfo::lookup(int32_t dataCodewords,
    121                                        SymbolShapeHint shape,
    122                                        int32_t& e) {
    123   return lookup(dataCodewords, shape, true, e);
    124 }
    125 CBC_SymbolInfo* CBC_SymbolInfo::lookup(int32_t dataCodewords,
    126                                        bool allowRectangular,
    127                                        bool fail,
    128                                        int32_t& e) {
    129   SymbolShapeHint shape = allowRectangular ? FORCE_NONE : FORCE_SQUARE;
    130   return lookup(dataCodewords, shape, fail, e);
    131 }
    132 CBC_SymbolInfo* CBC_SymbolInfo::lookup(int32_t dataCodewords,
    133                                        SymbolShapeHint shape,
    134                                        bool fail,
    135                                        int32_t& e) {
    136   return lookup(dataCodewords, shape, nullptr, nullptr, fail, e);
    137 }
    138 CBC_SymbolInfo* CBC_SymbolInfo::lookup(int32_t dataCodewords,
    139                                        SymbolShapeHint shape,
    140                                        CBC_Dimension* minSize,
    141                                        CBC_Dimension* maxSize,
    142                                        bool fail,
    143                                        int32_t& e) {
    144   for (size_t i = 0; i < kSymbolsCount; i++) {
    145     CBC_SymbolInfo* symbol = g_symbols[i];
    146     if (shape == FORCE_SQUARE && symbol->m_rectangular) {
    147       continue;
    148     }
    149     if (shape == FORCE_RECTANGLE && !symbol->m_rectangular) {
    150       continue;
    151     }
    152     if (minSize && (symbol->getSymbolWidth(e) < minSize->getWidth() ||
    153                     symbol->getSymbolHeight(e) < minSize->getHeight())) {
    154       if (e != BCExceptionNO)
    155         return nullptr;
    156       continue;
    157     }
    158     if (maxSize && (symbol->getSymbolWidth(e) > maxSize->getWidth() ||
    159                     symbol->getSymbolHeight(e) > maxSize->getHeight())) {
    160       if (e != BCExceptionNO)
    161         return nullptr;
    162       continue;
    163     }
    164     if (dataCodewords <= symbol->m_dataCapacity) {
    165       return symbol;
    166     }
    167   }
    168   if (fail)
    169     e = BCExceptionIllegalDataCodewords;
    170   return nullptr;
    171 }
    172 
    173 int32_t CBC_SymbolInfo::getHorizontalDataRegions(int32_t& e) {
    174   switch (m_dataRegions) {
    175     case 1:
    176       return 1;
    177     case 2:
    178       return 2;
    179     case 4:
    180       return 2;
    181     case 16:
    182       return 4;
    183     case 36:
    184       return 6;
    185     default:
    186       e = BCExceptionCannotHandleThisNumberOfDataRegions;
    187       return 0;
    188   }
    189 }
    190 int32_t CBC_SymbolInfo::getVerticalDataRegions(int32_t& e) {
    191   switch (m_dataRegions) {
    192     case 1:
    193       return 1;
    194     case 2:
    195       return 1;
    196     case 4:
    197       return 2;
    198     case 16:
    199       return 4;
    200     case 36:
    201       return 6;
    202     default:
    203       e = BCExceptionCannotHandleThisNumberOfDataRegions;
    204       return 0;
    205   }
    206 }
    207 int32_t CBC_SymbolInfo::getSymbolDataWidth(int32_t& e) {
    208   return getHorizontalDataRegions(e) * m_matrixWidth;
    209 }
    210 int32_t CBC_SymbolInfo::getSymbolDataHeight(int32_t& e) {
    211   return getVerticalDataRegions(e) * m_matrixHeight;
    212 }
    213 int32_t CBC_SymbolInfo::getSymbolWidth(int32_t& e) {
    214   return getSymbolDataWidth(e) + (getHorizontalDataRegions(e) * 2);
    215 }
    216 int32_t CBC_SymbolInfo::getSymbolHeight(int32_t& e) {
    217   return getSymbolDataHeight(e) + (getVerticalDataRegions(e) * 2);
    218 }
    219 int32_t CBC_SymbolInfo::getCodewordCount() {
    220   return m_dataCapacity + m_errorCodewords;
    221 }
    222 int32_t CBC_SymbolInfo::getInterleavedBlockCount() {
    223   return m_dataCapacity / m_rsBlockData;
    224 }
    225 int32_t CBC_SymbolInfo::getDataLengthForInterleavedBlock(int32_t index) {
    226   return m_rsBlockData;
    227 }
    228 int32_t CBC_SymbolInfo::getErrorLengthForInterleavedBlock(int32_t index) {
    229   return m_rsBlockError;
    230 }
    231