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 2007 ZXing authors
      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/src/fxbarcode/barcode.h"
     24 #include "xfa/src/fxbarcode/common/BC_CommonBitMatrix.h"
     25 #include "BC_DataMatrixVersion.h"
     26 #include "BC_DataMatrixBitMatrixParser.h"
     27 CBC_DataMatrixBitMatrixParser::CBC_DataMatrixBitMatrixParser() {
     28   m_mappingBitMatrix = NULL;
     29   m_version = NULL;
     30   m_readMappingMatrix = NULL;
     31 }
     32 void CBC_DataMatrixBitMatrixParser::Init(CBC_CommonBitMatrix* bitMatrix,
     33                                          int32_t& e) {
     34   int32_t dimension = bitMatrix->GetHeight();
     35   if (dimension < 8 || dimension > 144 || (dimension & 0x01) != 0) {
     36     e = BCExceptionFormatException;
     37     return;
     38   }
     39   m_version = ReadVersion(bitMatrix, e);
     40   BC_EXCEPTION_CHECK_ReturnVoid(e);
     41   m_mappingBitMatrix = ExtractDataRegion(bitMatrix, e);
     42   BC_EXCEPTION_CHECK_ReturnVoid(e);
     43   m_readMappingMatrix = new CBC_CommonBitMatrix();
     44   m_readMappingMatrix->Init(m_mappingBitMatrix->GetWidth(),
     45                             m_mappingBitMatrix->GetHeight());
     46 }
     47 CBC_DataMatrixBitMatrixParser::~CBC_DataMatrixBitMatrixParser() {
     48   if (m_mappingBitMatrix != NULL) {
     49     delete m_mappingBitMatrix;
     50   }
     51   m_mappingBitMatrix = NULL;
     52   if (m_readMappingMatrix != NULL) {
     53     delete m_readMappingMatrix;
     54   }
     55   m_readMappingMatrix = NULL;
     56 }
     57 CBC_DataMatrixVersion* CBC_DataMatrixBitMatrixParser::GetVersion() {
     58   return m_version;
     59 }
     60 CBC_DataMatrixVersion* CBC_DataMatrixBitMatrixParser::ReadVersion(
     61     CBC_CommonBitMatrix* bitMatrix,
     62     int32_t& e) {
     63   int32_t rows = bitMatrix->GetHeight();
     64   int32_t columns = bitMatrix->GetWidth();
     65   CBC_DataMatrixVersion* temp =
     66       CBC_DataMatrixVersion::GetVersionForDimensions(rows, columns, e);
     67   BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
     68   return temp;
     69 }
     70 CFX_ByteArray* CBC_DataMatrixBitMatrixParser::ReadCodewords(int32_t& e) {
     71   CBC_AutoPtr<CFX_ByteArray> result(new CFX_ByteArray());
     72   result->SetSize(m_version->GetTotalCodewords());
     73   int32_t resultOffset = 0;
     74   int32_t row = 4;
     75   int32_t column = 0;
     76   int32_t numRows = m_mappingBitMatrix->GetHeight();
     77   int32_t numColumns = m_mappingBitMatrix->GetWidth();
     78   FX_BOOL corner1Read = FALSE;
     79   FX_BOOL corner2Read = FALSE;
     80   FX_BOOL corner3Read = FALSE;
     81   FX_BOOL corner4Read = FALSE;
     82   do {
     83     if ((row == numRows) && (column == 0) && !corner1Read) {
     84       (*result)[resultOffset++] = (uint8_t)ReadCorner1(numRows, numColumns);
     85       row -= 2;
     86       column += 2;
     87       corner1Read = TRUE;
     88     } else if ((row == numRows - 2) && (column == 0) &&
     89                ((numColumns & 0x03) != 0) && !corner2Read) {
     90       (*result)[resultOffset++] = (uint8_t)ReadCorner2(numRows, numColumns);
     91       row -= 2;
     92       column += 2;
     93       corner2Read = TRUE;
     94     } else if ((row == numRows + 4) && (column == 2) &&
     95                ((numColumns & 0x07) == 0) && !corner3Read) {
     96       (*result)[resultOffset++] = (uint8_t)ReadCorner3(numRows, numColumns);
     97       row -= 2;
     98       column += 2;
     99       corner3Read = TRUE;
    100     } else if ((row == numRows - 2) && (column == 0) &&
    101                ((numColumns & 0x07) == 4) && !corner4Read) {
    102       (*result)[resultOffset++] = (uint8_t)ReadCorner4(numRows, numColumns);
    103       row -= 2;
    104       column += 2;
    105       corner4Read = TRUE;
    106     } else {
    107       do {
    108         if ((row < numRows) && (column >= 0) &&
    109             !m_readMappingMatrix->Get(column, row)) {
    110           if (resultOffset < (*result).GetSize()) {
    111             (*result)[resultOffset++] =
    112                 (uint8_t)ReadUtah(row, column, numRows, numColumns);
    113           }
    114         }
    115         row -= 2;
    116         column += 2;
    117       } while ((row >= 0) && (column < numColumns));
    118       row += 1;
    119       column += 3;
    120       do {
    121         if ((row >= 0) && (column < numColumns) &&
    122             !m_readMappingMatrix->Get(column, row)) {
    123           if (resultOffset < (*result).GetSize()) {
    124             (*result)[resultOffset++] =
    125                 (uint8_t)ReadUtah(row, column, numRows, numColumns);
    126           }
    127         }
    128         row += 2;
    129         column -= 2;
    130       } while ((row < numRows) && (column >= 0));
    131       row += 3;
    132       column += 1;
    133     }
    134   } while ((row < numRows) || (column < numColumns));
    135   if (resultOffset != m_version->GetTotalCodewords()) {
    136     e = BCExceptionFormatException;
    137     return NULL;
    138   }
    139   return result.release();
    140 }
    141 FX_BOOL CBC_DataMatrixBitMatrixParser::ReadModule(int32_t row,
    142                                                   int32_t column,
    143                                                   int32_t numRows,
    144                                                   int32_t numColumns) {
    145   if (row < 0) {
    146     row += numRows;
    147     column += 4 - ((numRows + 4) & 0x07);
    148   }
    149   if (column < 0) {
    150     column += numColumns;
    151     row += 4 - ((numColumns + 4) & 0x07);
    152   }
    153   m_readMappingMatrix->Set(column, row);
    154   return m_mappingBitMatrix->Get(column, row);
    155 }
    156 int32_t CBC_DataMatrixBitMatrixParser::ReadUtah(int32_t row,
    157                                                 int32_t column,
    158                                                 int32_t numRows,
    159                                                 int32_t numColumns) {
    160   int32_t currentByte = 0;
    161   if (ReadModule(row - 2, column - 2, numRows, numColumns)) {
    162     currentByte |= 1;
    163   }
    164   currentByte <<= 1;
    165   if (ReadModule(row - 2, column - 1, numRows, numColumns)) {
    166     currentByte |= 1;
    167   }
    168   currentByte <<= 1;
    169   if (ReadModule(row - 1, column - 2, numRows, numColumns)) {
    170     currentByte |= 1;
    171   }
    172   currentByte <<= 1;
    173   if (ReadModule(row - 1, column - 1, numRows, numColumns)) {
    174     currentByte |= 1;
    175   }
    176   currentByte <<= 1;
    177   if (ReadModule(row - 1, column, numRows, numColumns)) {
    178     currentByte |= 1;
    179   }
    180   currentByte <<= 1;
    181   if (ReadModule(row, column - 2, numRows, numColumns)) {
    182     currentByte |= 1;
    183   }
    184   currentByte <<= 1;
    185   if (ReadModule(row, column - 1, numRows, numColumns)) {
    186     currentByte |= 1;
    187   }
    188   currentByte <<= 1;
    189   if (ReadModule(row, column, numRows, numColumns)) {
    190     currentByte |= 1;
    191   }
    192   return currentByte;
    193 }
    194 int32_t CBC_DataMatrixBitMatrixParser::ReadCorner1(int32_t numRows,
    195                                                    int32_t numColumns) {
    196   int32_t currentByte = 0;
    197   if (ReadModule(numRows - 1, 0, numRows, numColumns)) {
    198     currentByte |= 1;
    199   }
    200   currentByte <<= 1;
    201   if (ReadModule(numRows - 1, 1, numRows, numColumns)) {
    202     currentByte |= 1;
    203   }
    204   currentByte <<= 1;
    205   if (ReadModule(numRows - 1, 2, numRows, numColumns)) {
    206     currentByte |= 1;
    207   }
    208   currentByte <<= 1;
    209   if (ReadModule(0, numColumns - 2, numRows, numColumns)) {
    210     currentByte |= 1;
    211   }
    212   currentByte <<= 1;
    213   if (ReadModule(0, numColumns - 1, numRows, numColumns)) {
    214     currentByte |= 1;
    215   }
    216   currentByte <<= 1;
    217   if (ReadModule(1, numColumns - 1, numRows, numColumns)) {
    218     currentByte |= 1;
    219   }
    220   currentByte <<= 1;
    221   if (ReadModule(2, numColumns - 1, numRows, numColumns)) {
    222     currentByte |= 1;
    223   }
    224   currentByte <<= 1;
    225   if (ReadModule(3, numColumns - 1, numRows, numColumns)) {
    226     currentByte |= 1;
    227   }
    228   return currentByte;
    229 }
    230 int32_t CBC_DataMatrixBitMatrixParser::ReadCorner2(int32_t numRows,
    231                                                    int32_t numColumns) {
    232   int32_t currentByte = 0;
    233   if (ReadModule(numRows - 3, 0, numRows, numColumns)) {
    234     currentByte |= 1;
    235   }
    236   currentByte <<= 1;
    237   if (ReadModule(numRows - 2, 0, numRows, numColumns)) {
    238     currentByte |= 1;
    239   }
    240   currentByte <<= 1;
    241   if (ReadModule(numRows - 1, 0, numRows, numColumns)) {
    242     currentByte |= 1;
    243   }
    244   currentByte <<= 1;
    245   if (ReadModule(0, numColumns - 4, numRows, numColumns)) {
    246     currentByte |= 1;
    247   }
    248   currentByte <<= 1;
    249   if (ReadModule(0, numColumns - 3, numRows, numColumns)) {
    250     currentByte |= 1;
    251   }
    252   currentByte <<= 1;
    253   if (ReadModule(0, numColumns - 2, numRows, numColumns)) {
    254     currentByte |= 1;
    255   }
    256   currentByte <<= 1;
    257   if (ReadModule(0, numColumns - 1, numRows, numColumns)) {
    258     currentByte |= 1;
    259   }
    260   currentByte <<= 1;
    261   if (ReadModule(1, numColumns - 1, numRows, numColumns)) {
    262     currentByte |= 1;
    263   }
    264   return currentByte;
    265 }
    266 int32_t CBC_DataMatrixBitMatrixParser::ReadCorner3(int32_t numRows,
    267                                                    int32_t numColumns) {
    268   int32_t currentByte = 0;
    269   if (ReadModule(numRows - 1, 0, numRows, numColumns)) {
    270     currentByte |= 1;
    271   }
    272   currentByte <<= 1;
    273   if (ReadModule(numRows - 1, numColumns - 1, numRows, numColumns)) {
    274     currentByte |= 1;
    275   }
    276   currentByte <<= 1;
    277   if (ReadModule(0, numColumns - 3, numRows, numColumns)) {
    278     currentByte |= 1;
    279   }
    280   currentByte <<= 1;
    281   if (ReadModule(0, numColumns - 2, numRows, numColumns)) {
    282     currentByte |= 1;
    283   }
    284   currentByte <<= 1;
    285   if (ReadModule(0, numColumns - 1, numRows, numColumns)) {
    286     currentByte |= 1;
    287   }
    288   currentByte <<= 1;
    289   if (ReadModule(1, numColumns - 3, numRows, numColumns)) {
    290     currentByte |= 1;
    291   }
    292   currentByte <<= 1;
    293   if (ReadModule(1, numColumns - 2, numRows, numColumns)) {
    294     currentByte |= 1;
    295   }
    296   currentByte <<= 1;
    297   if (ReadModule(1, numColumns - 1, numRows, numColumns)) {
    298     currentByte |= 1;
    299   }
    300   return currentByte;
    301 }
    302 int32_t CBC_DataMatrixBitMatrixParser::ReadCorner4(int32_t numRows,
    303                                                    int32_t numColumns) {
    304   int32_t currentByte = 0;
    305   if (ReadModule(numRows - 3, 0, numRows, numColumns)) {
    306     currentByte |= 1;
    307   }
    308   currentByte <<= 1;
    309   if (ReadModule(numRows - 2, 0, numRows, numColumns)) {
    310     currentByte |= 1;
    311   }
    312   currentByte <<= 1;
    313   if (ReadModule(numRows - 1, 0, numRows, numColumns)) {
    314     currentByte |= 1;
    315   }
    316   currentByte <<= 1;
    317   if (ReadModule(0, numColumns - 2, numRows, numColumns)) {
    318     currentByte |= 1;
    319   }
    320   currentByte <<= 1;
    321   if (ReadModule(0, numColumns - 1, numRows, numColumns)) {
    322     currentByte |= 1;
    323   }
    324   currentByte <<= 1;
    325   if (ReadModule(1, numColumns - 1, numRows, numColumns)) {
    326     currentByte |= 1;
    327   }
    328   currentByte <<= 1;
    329   if (ReadModule(2, numColumns - 1, numRows, numColumns)) {
    330     currentByte |= 1;
    331   }
    332   currentByte <<= 1;
    333   if (ReadModule(3, numColumns - 1, numRows, numColumns)) {
    334     currentByte |= 1;
    335   }
    336   return currentByte;
    337 }
    338 CBC_CommonBitMatrix* CBC_DataMatrixBitMatrixParser::ExtractDataRegion(
    339     CBC_CommonBitMatrix* bitMatrix,
    340     int32_t& e) {
    341   int32_t symbolSizeRows = m_version->GetSymbolSizeRows();
    342   int32_t symbolSizeColumns = m_version->GetSymbolSizeColumns();
    343   if (bitMatrix->GetHeight() != symbolSizeRows) {
    344     e = BCExceptionCanNotCallGetDimensionOnNonSquareMatrix;
    345     return NULL;
    346   }
    347   int32_t dataRegionSizeRows = m_version->GetDataRegionSizeRows();
    348   int32_t dataRegionSizeColumns = m_version->GetDataRegionSizeColumns();
    349   int32_t numDataRegionsRow = symbolSizeRows / dataRegionSizeRows;
    350   int32_t numDataRegionsColumn = symbolSizeColumns / dataRegionSizeColumns;
    351   int32_t sizeDataRegionRow = numDataRegionsRow * dataRegionSizeRows;
    352   int32_t sizeDataRegionColumn = numDataRegionsColumn * dataRegionSizeColumns;
    353   CBC_CommonBitMatrix* bitMatrixWithoutAlignment = new CBC_CommonBitMatrix();
    354   bitMatrixWithoutAlignment->Init(sizeDataRegionColumn, sizeDataRegionRow);
    355   int32_t dataRegionRow;
    356   for (dataRegionRow = 0; dataRegionRow < numDataRegionsRow; ++dataRegionRow) {
    357     int32_t dataRegionRowOffset = dataRegionRow * dataRegionSizeRows;
    358     int32_t dataRegionColumn;
    359     for (dataRegionColumn = 0; dataRegionColumn < numDataRegionsColumn;
    360          ++dataRegionColumn) {
    361       int32_t dataRegionColumnOffset = dataRegionColumn * dataRegionSizeColumns;
    362       int32_t i;
    363       for (i = 0; i < dataRegionSizeRows; ++i) {
    364         int32_t readRowOffset =
    365             dataRegionRow * (dataRegionSizeRows + 2) + 1 + i;
    366         int32_t writeRowOffset = dataRegionRowOffset + i;
    367         int32_t j;
    368         for (j = 0; j < dataRegionSizeColumns; ++j) {
    369           int32_t readColumnOffset =
    370               dataRegionColumn * (dataRegionSizeColumns + 2) + 1 + j;
    371           if (bitMatrix->Get(readColumnOffset, readRowOffset)) {
    372             int32_t writeColumnOffset = dataRegionColumnOffset + j;
    373             bitMatrixWithoutAlignment->Set(writeColumnOffset, writeRowOffset);
    374           }
    375         }
    376       }
    377     }
    378   }
    379   return bitMatrixWithoutAlignment;
    380 }
    381