diff options
author | Dan Sinclair <dsinclair@chromium.org> | 2016-03-14 14:14:16 -0400 |
---|---|---|
committer | Dan Sinclair <dsinclair@chromium.org> | 2016-03-14 14:14:16 -0400 |
commit | 1770c021cf998ff1b33855b1397f6ea8ff9f7cd7 (patch) | |
tree | 285e39abd4b5872d8cd632b9e331b0667fdc3eae /xfa/fxbarcode | |
parent | f766ad219f66543654520f6a1955836f519e26d1 (diff) | |
download | pdfium-1770c021cf998ff1b33855b1397f6ea8ff9f7cd7.tar.xz |
Move xfa/src up to xfa/.
This CL moves the xfa/src files up to the xfa/ directory and fixes the includes,
include guards, and build files.
R=tsepez@chromium.org
Review URL: https://codereview.chromium.org/1803723002 .
Diffstat (limited to 'xfa/fxbarcode')
238 files changed, 28056 insertions, 0 deletions
diff --git a/xfa/fxbarcode/BC_BarCode.cpp b/xfa/fxbarcode/BC_BarCode.cpp new file mode 100644 index 0000000000..11f47b5578 --- /dev/null +++ b/xfa/fxbarcode/BC_BarCode.cpp @@ -0,0 +1,877 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com +// Original code is licensed as follows: +/* + * Copyright 2011 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "xfa/fxbarcode/BC_Binarizer.h" +#include "xfa/fxbarcode/BC_BinaryBitmap.h" +#include "xfa/fxbarcode/BC_BinaryBitmap.h" +#include "xfa/fxbarcode/BC_BufferedImageLuminanceSource.h" +#include "xfa/fxbarcode/BC_DecoderResult.h" +#include "xfa/fxbarcode/BC_LuminanceSource.h" +#include "xfa/fxbarcode/BC_Reader.h" +#include "xfa/fxbarcode/BC_ResultPoint.h" +#include "xfa/fxbarcode/BC_TwoDimWriter.h" +#include "xfa/fxbarcode/BC_UtilCodingConvert.h" +#include "xfa/fxbarcode/BC_Writer.h" +#include "xfa/fxbarcode/common/BC_CommonBitArray.h" +#include "xfa/fxbarcode/common/BC_CommonBitMatrix.h" +#include "xfa/fxbarcode/common/BC_CommonBitMatrix.h" +#include "xfa/fxbarcode/common/BC_CommonDecoderResult.h" +#include "xfa/fxbarcode/common/BC_GlobalHistogramBinarizer.h" +#include "xfa/fxbarcode/datamatrix/BC_DataMatrixReader.h" +#include "xfa/fxbarcode/datamatrix/BC_DataMatrixWriter.h" +#include "xfa/fxbarcode/oned/BC_OneDReader.h" +#include "xfa/fxbarcode/oned/BC_OneDimReader.h" +#include "xfa/fxbarcode/oned/BC_OneDimWriter.h" +#include "xfa/fxbarcode/oned/BC_OnedCodaBarReader.h" +#include "xfa/fxbarcode/oned/BC_OnedCodaBarWriter.h" +#include "xfa/fxbarcode/oned/BC_OnedCode128Reader.h" +#include "xfa/fxbarcode/oned/BC_OnedCode128Writer.h" +#include "xfa/fxbarcode/oned/BC_OnedCode39Reader.h" +#include "xfa/fxbarcode/oned/BC_OnedCode39Writer.h" +#include "xfa/fxbarcode/oned/BC_OnedEAN13Reader.h" +#include "xfa/fxbarcode/oned/BC_OnedEAN13Writer.h" +#include "xfa/fxbarcode/oned/BC_OnedEAN8Reader.h" +#include "xfa/fxbarcode/oned/BC_OnedEAN8Writer.h" +#include "xfa/fxbarcode/oned/BC_OnedUPCAReader.h" +#include "xfa/fxbarcode/oned/BC_OnedUPCAWriter.h" +#include "xfa/fxbarcode/pdf417/BC_PDF417.h" +#include "xfa/fxbarcode/pdf417/BC_PDF417BarcodeMetadata.h" +#include "xfa/fxbarcode/pdf417/BC_PDF417BarcodeValue.h" +#include "xfa/fxbarcode/pdf417/BC_PDF417BoundingBox.h" +#include "xfa/fxbarcode/pdf417/BC_PDF417Codeword.h" +#include "xfa/fxbarcode/pdf417/BC_PDF417CodewordDecoder.h" +#include "xfa/fxbarcode/pdf417/BC_PDF417Common.h" +#include "xfa/fxbarcode/pdf417/BC_PDF417Compaction.h" +#include "xfa/fxbarcode/pdf417/BC_PDF417DecodedBitStreamParser.h" +#include "xfa/fxbarcode/pdf417/BC_PDF417DecodedBitStreamParser.h" +#include "xfa/fxbarcode/pdf417/BC_PDF417DecodedBitStreamParser.h" +#include "xfa/fxbarcode/pdf417/BC_PDF417DetectionResult.h" +#include "xfa/fxbarcode/pdf417/BC_PDF417DetectionResultColumn.h" +#include "xfa/fxbarcode/pdf417/BC_PDF417DetectionResultRowIndicatorColumn.h" +#include "xfa/fxbarcode/pdf417/BC_PDF417Detector.h" +#include "xfa/fxbarcode/pdf417/BC_PDF417DetectorResult.h" +#include "xfa/fxbarcode/pdf417/BC_PDF417DetectorResult.h" +#include "xfa/fxbarcode/pdf417/BC_PDF417ECErrorCorrection.h" +#include "xfa/fxbarcode/pdf417/BC_PDF417ECModulusGF.h" +#include "xfa/fxbarcode/pdf417/BC_PDF417ECModulusPoly.h" +#include "xfa/fxbarcode/pdf417/BC_PDF417HighLevelEncoder.h" +#include "xfa/fxbarcode/pdf417/BC_PDF417Reader.h" +#include "xfa/fxbarcode/pdf417/BC_PDF417ScanningDecoder.h" +#include "xfa/fxbarcode/pdf417/BC_PDF417Writer.h" +#include "xfa/fxbarcode/qrcode/BC_QRCodeReader.h" +#include "xfa/fxbarcode/qrcode/BC_QRCodeWriter.h" + +CBC_CodeBase::CBC_CodeBase() {} +CBC_CodeBase::~CBC_CodeBase() {} +FX_BOOL CBC_CodeBase::SetCharEncoding(int32_t encoding) { + if (m_pBCWriter) { + return m_pBCWriter->SetCharEncoding(encoding); + } + return FALSE; +} +FX_BOOL CBC_CodeBase::SetModuleHeight(int32_t moduleHeight) { + if (m_pBCWriter) { + return m_pBCWriter->SetModuleHeight(moduleHeight); + } + return FALSE; +} +FX_BOOL CBC_CodeBase::SetModuleWidth(int32_t moduleWidth) { + if (m_pBCWriter) { + return m_pBCWriter->SetModuleWidth(moduleWidth); + } + return FALSE; +} +FX_BOOL CBC_CodeBase::SetHeight(int32_t height) { + if (m_pBCWriter) { + return m_pBCWriter->SetHeight(height); + } + return FALSE; +} +FX_BOOL CBC_CodeBase::SetWidth(int32_t width) { + if (m_pBCWriter) { + return m_pBCWriter->SetWidth(width); + } + return FALSE; +} +void CBC_CodeBase::SetBackgroundColor(FX_ARGB backgroundColor) { + if (m_pBCWriter) { + m_pBCWriter->SetBackgroundColor(backgroundColor); + } +} +void CBC_CodeBase::SetBarcodeColor(FX_ARGB foregroundColor) { + if (m_pBCWriter) { + m_pBCWriter->SetBarcodeColor(foregroundColor); + } +} +CBC_OneCode::CBC_OneCode() {} +CBC_OneCode::~CBC_OneCode() {} +FX_BOOL CBC_OneCode::CheckContentValidity(const CFX_WideStringC& contents) { + if (m_pBCWriter) { + return ((CBC_OneDimWriter*)m_pBCWriter)->CheckContentValidity(contents); + } + return FALSE; +} +CFX_WideString CBC_OneCode::FilterContents(const CFX_WideStringC& contents) { + CFX_WideString tmp; + if (m_pBCWriter == NULL) { + return tmp; + } + return ((CBC_OneDimWriter*)m_pBCWriter)->FilterContents(contents); +} +void CBC_OneCode::SetPrintChecksum(FX_BOOL checksum) { + if (m_pBCWriter) { + ((CBC_OneDimWriter*)m_pBCWriter)->SetPrintChecksum(checksum); + } +} +void CBC_OneCode::SetDataLength(int32_t length) { + if (m_pBCWriter) { + ((CBC_OneDimWriter*)m_pBCWriter)->SetDataLength(length); + } +} +void CBC_OneCode::SetCalChecksum(FX_BOOL calc) { + if (m_pBCWriter) { + ((CBC_OneDimWriter*)m_pBCWriter)->SetCalcChecksum(calc); + } +} +FX_BOOL CBC_OneCode::SetFont(CFX_Font* cFont) { + if (m_pBCWriter) { + return ((CBC_OneDimWriter*)m_pBCWriter)->SetFont(cFont); + } + return FALSE; +} +void CBC_OneCode::SetFontSize(FX_FLOAT size) { + if (m_pBCWriter) { + ((CBC_OneDimWriter*)m_pBCWriter)->SetFontSize(size); + } +} +void CBC_OneCode::SetFontStyle(int32_t style) { + if (m_pBCWriter) { + ((CBC_OneDimWriter*)m_pBCWriter)->SetFontStyle(style); + } +} +void CBC_OneCode::SetFontColor(FX_ARGB color) { + if (m_pBCWriter) { + ((CBC_OneDimWriter*)m_pBCWriter)->SetFontColor(color); + } +} +CBC_Code39::CBC_Code39() { + m_pBCReader = (CBC_Reader*)new (CBC_OnedCode39Reader); + m_pBCWriter = (CBC_Writer*)new (CBC_OnedCode39Writer); +} +CBC_Code39::CBC_Code39(FX_BOOL usingCheckDigit) { + m_pBCReader = (CBC_Reader*)new CBC_OnedCode39Reader(usingCheckDigit); + m_pBCWriter = (CBC_Writer*)new CBC_OnedCode39Writer; +} +CBC_Code39::CBC_Code39(FX_BOOL usingCheckDigit, FX_BOOL extendedMode) { + m_pBCReader = + (CBC_Reader*)new CBC_OnedCode39Reader(usingCheckDigit, extendedMode); + m_pBCWriter = (CBC_Writer*)new CBC_OnedCode39Writer(extendedMode); +} +CBC_Code39::~CBC_Code39() { + if (m_pBCReader) { + delete (m_pBCReader); + m_pBCReader = NULL; + } + if (m_pBCWriter) { + delete (m_pBCWriter); + m_pBCWriter = NULL; + } +} +FX_BOOL CBC_Code39::Encode(const CFX_WideStringC& contents, + FX_BOOL isDevice, + int32_t& e) { + if (contents.IsEmpty()) { + e = BCExceptionNoContents; + return FALSE; + } + BCFORMAT format = BCFORMAT_CODE_39; + int32_t outWidth = 0; + int32_t outHeight = 0; + CFX_WideString filtercontents = + ((CBC_OnedCode39Writer*)m_pBCWriter)->FilterContents(contents); + CFX_WideString renderContents = + ((CBC_OnedCode39Writer*)m_pBCWriter)->RenderTextContents(contents); + m_renderContents = renderContents; + CFX_ByteString byteString = filtercontents.UTF8Encode(); + uint8_t* data = static_cast<CBC_OnedCode39Writer*>(m_pBCWriter) + ->Encode(byteString, format, outWidth, outHeight, e); + BC_EXCEPTION_CHECK_ReturnValue(e, FALSE); + ((CBC_OneDimWriter*)m_pBCWriter) + ->RenderResult(renderContents, data, outWidth, isDevice, e); + FX_Free(data); + BC_EXCEPTION_CHECK_ReturnValue(e, FALSE); + return TRUE; +} +FX_BOOL CBC_Code39::RenderDevice(CFX_RenderDevice* device, + const CFX_Matrix* matirx, + int32_t& e) { + CFX_WideString renderCon = ((CBC_OnedCode39Writer*)m_pBCWriter) + ->encodedContents(m_renderContents, e); + ((CBC_OneDimWriter*)m_pBCWriter) + ->RenderDeviceResult(device, matirx, renderCon, e); + BC_EXCEPTION_CHECK_ReturnValue(e, FALSE); + return TRUE; +} +FX_BOOL CBC_Code39::RenderBitmap(CFX_DIBitmap*& pOutBitmap, int32_t& e) { + CFX_WideString renderCon = ((CBC_OnedCode39Writer*)m_pBCWriter) + ->encodedContents(m_renderContents, e); + ((CBC_OneDimWriter*)m_pBCWriter) + ->RenderBitmapResult(pOutBitmap, renderCon, e); + BC_EXCEPTION_CHECK_ReturnValue(e, FALSE); + return TRUE; +} +CFX_WideString CBC_Code39::Decode(uint8_t* buf, + int32_t width, + int32_t hight, + int32_t& e) { + CFX_WideString str; + return str; +} +CFX_WideString CBC_Code39::Decode(CFX_DIBitmap* pBitmap, int32_t& e) { + CBC_BufferedImageLuminanceSource source(pBitmap); + CBC_GlobalHistogramBinarizer binarizer(&source); + CBC_BinaryBitmap bitmap(&binarizer); + CFX_ByteString str = m_pBCReader->Decode(&bitmap, 0, e); + BC_EXCEPTION_CHECK_ReturnValue(e, FX_WSTRC(L"")); + return CFX_WideString::FromUTF8(str, str.GetLength()); +} +FX_BOOL CBC_Code39::SetTextLocation(BC_TEXT_LOC location) { + if (m_pBCWriter) { + return ((CBC_OnedCode39Writer*)m_pBCWriter)->SetTextLocation(location); + } + return FALSE; +} +FX_BOOL CBC_Code39::SetWideNarrowRatio(int32_t ratio) { + if (m_pBCWriter) { + return ((CBC_OnedCode39Writer*)m_pBCWriter)->SetWideNarrowRatio(ratio); + } + return FALSE; +} +CBC_Codabar::CBC_Codabar() { + m_pBCReader = (CBC_Reader*)new (CBC_OnedCodaBarReader); + m_pBCWriter = (CBC_Writer*)new (CBC_OnedCodaBarWriter); +} +CBC_Codabar::~CBC_Codabar() { + if (m_pBCReader) { + delete (m_pBCReader); + m_pBCReader = NULL; + } + if (m_pBCWriter) { + delete (m_pBCWriter); + m_pBCWriter = NULL; + } +} +FX_BOOL CBC_Codabar::SetStartChar(FX_CHAR start) { + if (m_pBCWriter) { + return ((CBC_OnedCodaBarWriter*)m_pBCWriter)->SetStartChar(start); + } + return FALSE; +} +FX_BOOL CBC_Codabar::SetEndChar(FX_CHAR end) { + if (m_pBCWriter) { + return ((CBC_OnedCodaBarWriter*)m_pBCWriter)->SetEndChar(end); + } + return FALSE; +} +FX_BOOL CBC_Codabar::SetTextLocation(BC_TEXT_LOC location) { + return ((CBC_OnedCodaBarWriter*)m_pBCWriter)->SetTextLocation(location); +} +FX_BOOL CBC_Codabar::SetWideNarrowRatio(int32_t ratio) { + if (m_pBCWriter) { + return ((CBC_OnedCodaBarWriter*)m_pBCWriter)->SetWideNarrowRatio(ratio); + } + return FALSE; +} +FX_BOOL CBC_Codabar::Encode(const CFX_WideStringC& contents, + FX_BOOL isDevice, + int32_t& e) { + if (contents.IsEmpty()) { + e = BCExceptionNoContents; + return FALSE; + } + BCFORMAT format = BCFORMAT_CODABAR; + int32_t outWidth = 0; + int32_t outHeight = 0; + CFX_WideString filtercontents = + ((CBC_OneDimWriter*)m_pBCWriter)->FilterContents(contents); + CFX_ByteString byteString = filtercontents.UTF8Encode(); + m_renderContents = filtercontents; + uint8_t* data = static_cast<CBC_OnedCodaBarWriter*>(m_pBCWriter) + ->Encode(byteString, format, outWidth, outHeight, e); + BC_EXCEPTION_CHECK_ReturnValue(e, FALSE); + ((CBC_OneDimWriter*)m_pBCWriter) + ->RenderResult(filtercontents, data, outWidth, isDevice, e); + FX_Free(data); + BC_EXCEPTION_CHECK_ReturnValue(e, FALSE); + return TRUE; +} +FX_BOOL CBC_Codabar::RenderDevice(CFX_RenderDevice* device, + const CFX_Matrix* matirx, + int32_t& e) { + CFX_WideString renderCon = + ((CBC_OnedCodaBarWriter*)m_pBCWriter)->encodedContents(m_renderContents); + ((CBC_OneDimWriter*)m_pBCWriter) + ->RenderDeviceResult(device, matirx, renderCon, e); + BC_EXCEPTION_CHECK_ReturnValue(e, FALSE); + return TRUE; +} +FX_BOOL CBC_Codabar::RenderBitmap(CFX_DIBitmap*& pOutBitmap, int32_t& e) { + CFX_WideString renderCon = + ((CBC_OnedCodaBarWriter*)m_pBCWriter)->encodedContents(m_renderContents); + ((CBC_OneDimWriter*)m_pBCWriter) + ->RenderBitmapResult(pOutBitmap, renderCon, e); + BC_EXCEPTION_CHECK_ReturnValue(e, FALSE); + return TRUE; +} +CFX_WideString CBC_Codabar::Decode(uint8_t* buf, + int32_t width, + int32_t hight, + int32_t& e) { + CFX_WideString str; + return str; +} +CFX_WideString CBC_Codabar::Decode(CFX_DIBitmap* pBitmap, int32_t& e) { + CBC_BufferedImageLuminanceSource source(pBitmap); + CBC_GlobalHistogramBinarizer binarizer(&source); + CBC_BinaryBitmap bitmap(&binarizer); + CFX_ByteString str = m_pBCReader->Decode(&bitmap, 0, e); + BC_EXCEPTION_CHECK_ReturnValue(e, FX_WSTRC(L"")); + return CFX_WideString::FromUTF8(str, str.GetLength()); +} +CBC_Code128::CBC_Code128(BC_TYPE type) { + m_pBCReader = (CBC_Reader*)new (CBC_OnedCode128Reader); + m_pBCWriter = (CBC_Writer*)new CBC_OnedCode128Writer(type); +} +CBC_Code128::~CBC_Code128() { + if (m_pBCReader) { + delete (m_pBCReader); + m_pBCReader = NULL; + } + if (m_pBCWriter) { + delete (m_pBCWriter); + m_pBCWriter = NULL; + } +} +FX_BOOL CBC_Code128::SetTextLocation(BC_TEXT_LOC location) { + if (m_pBCWriter) { + return ((CBC_OnedCode128Writer*)m_pBCWriter)->SetTextLocation(location); + } + return FALSE; +} +FX_BOOL CBC_Code128::Encode(const CFX_WideStringC& contents, + FX_BOOL isDevice, + int32_t& e) { + if (contents.IsEmpty()) { + e = BCExceptionNoContents; + return FALSE; + } + BCFORMAT format = BCFORMAT_CODE_128; + int32_t outWidth = 0; + int32_t outHeight = 0; + CFX_WideString content = contents; + if (contents.GetLength() % 2 && + ((CBC_OnedCode128Writer*)m_pBCWriter)->GetType() == BC_CODE128_C) { + content += '0'; + } + CFX_WideString encodeContents = + ((CBC_OnedCode128Writer*)m_pBCWriter)->FilterContents(content); + m_renderContents = encodeContents; + CFX_ByteString byteString = encodeContents.UTF8Encode(); + uint8_t* data = static_cast<CBC_OnedCode128Writer*>(m_pBCWriter) + ->Encode(byteString, format, outWidth, outHeight, e); + BC_EXCEPTION_CHECK_ReturnValue(e, FALSE); + ((CBC_OneDimWriter*)m_pBCWriter) + ->RenderResult(encodeContents, data, outWidth, isDevice, e); + FX_Free(data); + BC_EXCEPTION_CHECK_ReturnValue(e, FALSE); + return TRUE; +} +FX_BOOL CBC_Code128::RenderDevice(CFX_RenderDevice* device, + const CFX_Matrix* matirx, + int32_t& e) { + ((CBC_OneDimWriter*)m_pBCWriter) + ->RenderDeviceResult(device, matirx, m_renderContents, e); + BC_EXCEPTION_CHECK_ReturnValue(e, FALSE); + return TRUE; +} +FX_BOOL CBC_Code128::RenderBitmap(CFX_DIBitmap*& pOutBitmap, int32_t& e) { + ((CBC_OneDimWriter*)m_pBCWriter) + ->RenderBitmapResult(pOutBitmap, m_renderContents, e); + BC_EXCEPTION_CHECK_ReturnValue(e, FALSE); + return TRUE; +} +CFX_WideString CBC_Code128::Decode(uint8_t* buf, + int32_t width, + int32_t hight, + int32_t& e) { + CFX_WideString str; + return str; +} +CFX_WideString CBC_Code128::Decode(CFX_DIBitmap* pBitmap, int32_t& e) { + CBC_BufferedImageLuminanceSource source(pBitmap); + CBC_GlobalHistogramBinarizer binarizer(&source); + CBC_BinaryBitmap bitmap(&binarizer); + CFX_ByteString str = m_pBCReader->Decode(&bitmap, 0, e); + BC_EXCEPTION_CHECK_ReturnValue(e, FX_WSTRC(L"")); + return CFX_WideString::FromUTF8(str, str.GetLength()); +} +CBC_EAN8::CBC_EAN8() { + m_pBCReader = (CBC_Reader*)new (CBC_OnedEAN8Reader); + m_pBCWriter = (CBC_Writer*)new (CBC_OnedEAN8Writer); +} +CBC_EAN8::~CBC_EAN8() { + if (m_pBCReader) { + delete (m_pBCReader); + m_pBCReader = NULL; + } + if (m_pBCWriter) { + delete (m_pBCWriter); + m_pBCWriter = NULL; + } +} +CFX_WideString CBC_EAN8::Preprocess(const CFX_WideStringC& contents) { + CFX_WideString encodeContents = + ((CBC_OnedEAN8Writer*)m_pBCWriter)->FilterContents(contents); + int32_t length = encodeContents.GetLength(); + if (length <= 7) { + for (int32_t i = 0; i < 7 - length; i++) { + encodeContents = FX_WCHAR('0') + encodeContents; + } + CFX_ByteString byteString = encodeContents.UTF8Encode(); + int32_t checksum = + ((CBC_OnedEAN8Writer*)m_pBCWriter)->CalcChecksum(byteString); + encodeContents += FX_WCHAR(checksum - 0 + '0'); + } + if (length > 8) { + encodeContents = encodeContents.Mid(0, 8); + } + return encodeContents; +} +FX_BOOL CBC_EAN8::Encode(const CFX_WideStringC& contents, + FX_BOOL isDevice, + int32_t& e) { + if (contents.IsEmpty()) { + e = BCExceptionNoContents; + return FALSE; + } + BCFORMAT format = BCFORMAT_EAN_8; + int32_t outWidth = 0; + int32_t outHeight = 0; + CFX_WideString encodeContents = Preprocess(contents); + CFX_ByteString byteString = encodeContents.UTF8Encode(); + m_renderContents = encodeContents; + uint8_t* data = static_cast<CBC_OnedEAN8Writer*>(m_pBCWriter) + ->Encode(byteString, format, outWidth, outHeight, e); + BC_EXCEPTION_CHECK_ReturnValue(e, FALSE); + ((CBC_OneDimWriter*)m_pBCWriter) + ->RenderResult(encodeContents, data, outWidth, isDevice, e); + FX_Free(data); + BC_EXCEPTION_CHECK_ReturnValue(e, FALSE); + return TRUE; +} +FX_BOOL CBC_EAN8::RenderDevice(CFX_RenderDevice* device, + const CFX_Matrix* matirx, + int32_t& e) { + ((CBC_OneDimWriter*)m_pBCWriter) + ->RenderDeviceResult(device, matirx, m_renderContents, e); + BC_EXCEPTION_CHECK_ReturnValue(e, FALSE); + return TRUE; +} +FX_BOOL CBC_EAN8::RenderBitmap(CFX_DIBitmap*& pOutBitmap, int32_t& e) { + ((CBC_OneDimWriter*)m_pBCWriter) + ->RenderBitmapResult(pOutBitmap, m_renderContents, e); + BC_EXCEPTION_CHECK_ReturnValue(e, FALSE); + return TRUE; +} +CFX_WideString CBC_EAN8::Decode(uint8_t* buf, + int32_t width, + int32_t hight, + int32_t& e) { + CFX_WideString str; + return str; +} +CFX_WideString CBC_EAN8::Decode(CFX_DIBitmap* pBitmap, int32_t& e) { + CBC_BufferedImageLuminanceSource source(pBitmap); + CBC_GlobalHistogramBinarizer binarizer(&source); + CBC_BinaryBitmap bitmap(&binarizer); + CFX_ByteString str = m_pBCReader->Decode(&bitmap, 0, e); + BC_EXCEPTION_CHECK_ReturnValue(e, FX_WSTRC(L"")); + return CFX_WideString::FromUTF8(str, str.GetLength()); +} +CBC_EAN13::CBC_EAN13() { + m_pBCReader = (CBC_Reader*)new (CBC_OnedEAN13Reader); + m_pBCWriter = (CBC_Writer*)new (CBC_OnedEAN13Writer); +} +CBC_EAN13::~CBC_EAN13() { + if (m_pBCReader) { + delete (m_pBCReader); + m_pBCReader = NULL; + } + if (m_pBCWriter) { + delete (m_pBCWriter); + m_pBCWriter = NULL; + } +} +CFX_WideString CBC_EAN13::Preprocess(const CFX_WideStringC& contents) { + CFX_WideString encodeContents = + ((CBC_OnedEAN8Writer*)m_pBCWriter)->FilterContents(contents); + int32_t length = encodeContents.GetLength(); + if (length <= 12) { + for (int32_t i = 0; i < 12 - length; i++) { + encodeContents = FX_WCHAR('0') + encodeContents; + } + CFX_ByteString byteString = encodeContents.UTF8Encode(); + int32_t checksum = + ((CBC_OnedEAN13Writer*)m_pBCWriter)->CalcChecksum(byteString); + byteString += checksum - 0 + '0'; + encodeContents = byteString.UTF8Decode(); + } + if (length > 13) { + encodeContents = encodeContents.Mid(0, 13); + } + return encodeContents; +} +FX_BOOL CBC_EAN13::Encode(const CFX_WideStringC& contents, + FX_BOOL isDevice, + int32_t& e) { + if (contents.IsEmpty()) { + e = BCExceptionNoContents; + return FALSE; + } + BCFORMAT format = BCFORMAT_EAN_13; + int32_t outWidth = 0; + int32_t outHeight = 0; + CFX_WideString encodeContents = Preprocess(contents); + CFX_ByteString byteString = encodeContents.UTF8Encode(); + m_renderContents = encodeContents; + uint8_t* data = static_cast<CBC_OnedEAN13Writer*>(m_pBCWriter) + ->Encode(byteString, format, outWidth, outHeight, e); + BC_EXCEPTION_CHECK_ReturnValue(e, FALSE); + ((CBC_OneDimWriter*)m_pBCWriter) + ->RenderResult(encodeContents, data, outWidth, isDevice, e); + FX_Free(data); + BC_EXCEPTION_CHECK_ReturnValue(e, FALSE); + return TRUE; +} +FX_BOOL CBC_EAN13::RenderDevice(CFX_RenderDevice* device, + const CFX_Matrix* matirx, + int32_t& e) { + ((CBC_OneDimWriter*)m_pBCWriter) + ->RenderDeviceResult(device, matirx, m_renderContents, e); + BC_EXCEPTION_CHECK_ReturnValue(e, FALSE); + return TRUE; +} +FX_BOOL CBC_EAN13::RenderBitmap(CFX_DIBitmap*& pOutBitmap, int32_t& e) { + ((CBC_OneDimWriter*)m_pBCWriter) + ->RenderBitmapResult(pOutBitmap, m_renderContents, e); + BC_EXCEPTION_CHECK_ReturnValue(e, FALSE); + return TRUE; +} +CFX_WideString CBC_EAN13::Decode(uint8_t* buf, + int32_t width, + int32_t hight, + int32_t& e) { + CFX_WideString str; + return str; +} +CFX_WideString CBC_EAN13::Decode(CFX_DIBitmap* pBitmap, int32_t& e) { + CBC_BufferedImageLuminanceSource source(pBitmap); + CBC_GlobalHistogramBinarizer binarizer(&source); + CBC_BinaryBitmap bitmap(&binarizer); + CFX_ByteString str = m_pBCReader->Decode(&bitmap, 0, e); + BC_EXCEPTION_CHECK_ReturnValue(e, FX_WSTRC(L"")); + return CFX_WideString::FromUTF8(str, str.GetLength()); +} +CBC_UPCA::CBC_UPCA() { + m_pBCReader = (CBC_Reader*)new (CBC_OnedUPCAReader); + ((CBC_OnedUPCAReader*)m_pBCReader)->Init(); + m_pBCWriter = (CBC_Writer*)new (CBC_OnedUPCAWriter); +} +CBC_UPCA::~CBC_UPCA() { + if (m_pBCReader) { + delete (m_pBCReader); + m_pBCReader = NULL; + } + if (m_pBCWriter) { + delete (m_pBCWriter); + m_pBCWriter = NULL; + } +} +CFX_WideString CBC_UPCA::Preprocess(const CFX_WideStringC& contents) { + CFX_WideString encodeContents = + ((CBC_OnedEAN8Writer*)m_pBCWriter)->FilterContents(contents); + int32_t length = encodeContents.GetLength(); + if (length <= 11) { + for (int32_t i = 0; i < 11 - length; i++) { + encodeContents = FX_WCHAR('0') + encodeContents; + } + CFX_ByteString byteString = encodeContents.UTF8Encode(); + int32_t checksum = + ((CBC_OnedUPCAWriter*)m_pBCWriter)->CalcChecksum(byteString); + byteString += checksum - 0 + '0'; + encodeContents = byteString.UTF8Decode(); + } + if (length > 12) { + encodeContents = encodeContents.Mid(0, 12); + } + return encodeContents; +} +FX_BOOL CBC_UPCA::Encode(const CFX_WideStringC& contents, + FX_BOOL isDevice, + int32_t& e) { + if (contents.IsEmpty()) { + e = BCExceptionNoContents; + return FALSE; + } + BCFORMAT format = BCFORMAT_UPC_A; + int32_t outWidth = 0; + int32_t outHeight = 0; + CFX_WideString encodeContents = Preprocess(contents); + CFX_ByteString byteString = encodeContents.UTF8Encode(); + m_renderContents = encodeContents; + ((CBC_OnedUPCAWriter*)m_pBCWriter)->Init(); + uint8_t* data = static_cast<CBC_OnedUPCAWriter*>(m_pBCWriter) + ->Encode(byteString, format, outWidth, outHeight, e); + BC_EXCEPTION_CHECK_ReturnValue(e, FALSE); + ((CBC_OneDimWriter*)m_pBCWriter) + ->RenderResult(encodeContents, data, outWidth, isDevice, e); + FX_Free(data); + BC_EXCEPTION_CHECK_ReturnValue(e, FALSE); + return TRUE; +} +FX_BOOL CBC_UPCA::RenderDevice(CFX_RenderDevice* device, + const CFX_Matrix* matirx, + int32_t& e) { + ((CBC_OneDimWriter*)m_pBCWriter) + ->RenderDeviceResult(device, matirx, m_renderContents, e); + BC_EXCEPTION_CHECK_ReturnValue(e, FALSE); + return TRUE; +} +FX_BOOL CBC_UPCA::RenderBitmap(CFX_DIBitmap*& pOutBitmap, int32_t& e) { + ((CBC_OneDimWriter*)m_pBCWriter) + ->RenderBitmapResult(pOutBitmap, m_renderContents, e); + BC_EXCEPTION_CHECK_ReturnValue(e, FALSE); + return TRUE; +} +CFX_WideString CBC_UPCA::Decode(uint8_t* buf, + int32_t width, + int32_t hight, + int32_t& e) { + CFX_WideString str; + return str; +} +CFX_WideString CBC_UPCA::Decode(CFX_DIBitmap* pBitmap, int32_t& e) { + CBC_BufferedImageLuminanceSource source(pBitmap); + CBC_GlobalHistogramBinarizer binarizer(&source); + CBC_BinaryBitmap bitmap(&binarizer); + CFX_ByteString str = m_pBCReader->Decode(&bitmap, 0, e); + BC_EXCEPTION_CHECK_ReturnValue(e, FX_WSTRC(L"")); + return CFX_WideString::FromUTF8(str, str.GetLength()); +} +CBC_QRCode::CBC_QRCode() { + m_pBCReader = (CBC_Reader*)new (CBC_QRCodeReader); + ((CBC_QRCodeReader*)m_pBCReader)->Init(); + m_pBCWriter = (CBC_Writer*)new (CBC_QRCodeWriter); +} +CBC_QRCode::~CBC_QRCode() { + if (m_pBCReader) { + delete (m_pBCReader); + m_pBCReader = NULL; + } + if (m_pBCWriter) { + delete (m_pBCWriter); + m_pBCWriter = NULL; + } +} +FX_BOOL CBC_QRCode::SetVersion(int32_t version) { + if (version < 0 || version > 40) { + return FALSE; + } + if (m_pBCWriter == NULL) { + return FALSE; + } + return ((CBC_QRCodeWriter*)m_pBCWriter)->SetVersion(version); +} +FX_BOOL CBC_QRCode::SetErrorCorrectionLevel(int32_t level) { + if (level < 0 || level > 3) { + return FALSE; + } + if (m_pBCWriter == NULL) { + return FALSE; + } + return ((CBC_TwoDimWriter*)m_pBCWriter)->SetErrorCorrectionLevel(level); +} +FX_BOOL CBC_QRCode::Encode(const CFX_WideStringC& contents, + FX_BOOL isDevice, + int32_t& e) { + int32_t outWidth = 0; + int32_t outHeight = 0; + uint8_t* data = ((CBC_QRCodeWriter*)m_pBCWriter) + ->Encode(contents, ((CBC_QRCodeWriter*)m_pBCWriter) + ->GetErrorCorrectionLevel(), + outWidth, outHeight, e); + BC_EXCEPTION_CHECK_ReturnValue(e, FALSE); + ((CBC_TwoDimWriter*)m_pBCWriter)->RenderResult(data, outWidth, outHeight, e); + FX_Free(data); + BC_EXCEPTION_CHECK_ReturnValue(e, FALSE); + return TRUE; +} +FX_BOOL CBC_QRCode::RenderDevice(CFX_RenderDevice* device, + const CFX_Matrix* matirx, + int32_t& e) { + ((CBC_TwoDimWriter*)m_pBCWriter)->RenderDeviceResult(device, matirx); + return TRUE; +} +FX_BOOL CBC_QRCode::RenderBitmap(CFX_DIBitmap*& pOutBitmap, int32_t& e) { + ((CBC_TwoDimWriter*)m_pBCWriter)->RenderBitmapResult(pOutBitmap, e); + BC_EXCEPTION_CHECK_ReturnValue(e, FALSE); + return TRUE; +} +CFX_WideString CBC_QRCode::Decode(uint8_t* buf, + int32_t width, + int32_t hight, + int32_t& e) { + CFX_WideString str; + return str; +} +CFX_WideString CBC_QRCode::Decode(CFX_DIBitmap* pBitmap, int32_t& e) { + CBC_BufferedImageLuminanceSource source(pBitmap); + CBC_GlobalHistogramBinarizer binarizer(&source); + CBC_BinaryBitmap bitmap(&binarizer); + CFX_ByteString retStr = m_pBCReader->Decode(&bitmap, 0, e); + BC_EXCEPTION_CHECK_ReturnValue(e, FX_WSTRC(L"")); + return CFX_WideString::FromUTF8(retStr, retStr.GetLength()); +} +CBC_PDF417I::CBC_PDF417I() { + m_pBCReader = (CBC_Reader*)new (CBC_PDF417Reader); + m_pBCWriter = (CBC_Writer*)new (CBC_PDF417Writer); +} +CBC_PDF417I::~CBC_PDF417I() { + if (m_pBCReader) { + delete (m_pBCReader); + m_pBCReader = NULL; + } + if (m_pBCWriter) { + delete (m_pBCWriter); + m_pBCWriter = NULL; + } +} +FX_BOOL CBC_PDF417I::SetErrorCorrectionLevel(int32_t level) { + ((CBC_PDF417Writer*)m_pBCWriter)->SetErrorCorrectionLevel(level); + return TRUE; +} +void CBC_PDF417I::SetTruncated(FX_BOOL truncated) { + ((CBC_PDF417Writer*)m_pBCWriter)->SetTruncated(truncated); +} +FX_BOOL CBC_PDF417I::Encode(const CFX_WideStringC& contents, + FX_BOOL isDevice, + int32_t& e) { + int32_t outWidth = 0; + int32_t outHeight = 0; + uint8_t* data = ((CBC_PDF417Writer*)m_pBCWriter) + ->Encode(contents, outWidth, outHeight, e); + BC_EXCEPTION_CHECK_ReturnValue(e, FALSE); + ((CBC_TwoDimWriter*)m_pBCWriter)->RenderResult(data, outWidth, outHeight, e); + FX_Free(data); + BC_EXCEPTION_CHECK_ReturnValue(e, FALSE); + return TRUE; +} +FX_BOOL CBC_PDF417I::RenderDevice(CFX_RenderDevice* device, + const CFX_Matrix* matirx, + int32_t& e) { + ((CBC_TwoDimWriter*)m_pBCWriter)->RenderDeviceResult(device, matirx); + return TRUE; +} +FX_BOOL CBC_PDF417I::RenderBitmap(CFX_DIBitmap*& pOutBitmap, int32_t& e) { + ((CBC_TwoDimWriter*)m_pBCWriter)->RenderBitmapResult(pOutBitmap, e); + BC_EXCEPTION_CHECK_ReturnValue(e, FALSE); + return TRUE; +} +CFX_WideString CBC_PDF417I::Decode(uint8_t* buf, + int32_t width, + int32_t hight, + int32_t& e) { + CFX_WideString str; + return str; +} +CFX_WideString CBC_PDF417I::Decode(CFX_DIBitmap* pBitmap, int32_t& e) { + CBC_BufferedImageLuminanceSource source(pBitmap); + CBC_GlobalHistogramBinarizer binarizer(&source); + CBC_BinaryBitmap bitmap(&binarizer); + CFX_ByteString bytestring = m_pBCReader->Decode(&bitmap, 0, e); + BC_EXCEPTION_CHECK_ReturnValue(e, FX_WSTRC(L"")); + return CFX_WideString::FromUTF8(bytestring, bytestring.GetLength()); +} +CBC_DataMatrix::CBC_DataMatrix() { + m_pBCReader = (CBC_Reader*)new (CBC_DataMatrixReader); + ((CBC_DataMatrixReader*)m_pBCReader)->Init(); + m_pBCWriter = (CBC_Writer*)new (CBC_DataMatrixWriter); +} +CBC_DataMatrix::~CBC_DataMatrix() { + if (m_pBCReader) { + delete (m_pBCReader); + m_pBCReader = NULL; + } + if (m_pBCWriter) { + delete (m_pBCWriter); + m_pBCWriter = NULL; + } +} +FX_BOOL CBC_DataMatrix::Encode(const CFX_WideStringC& contents, + FX_BOOL isDevice, + int32_t& e) { + int32_t outWidth = 0; + int32_t outHeight = 0; + uint8_t* data = ((CBC_DataMatrixWriter*)m_pBCWriter) + ->Encode(contents, outWidth, outHeight, e); + BC_EXCEPTION_CHECK_ReturnValue(e, FALSE); + ((CBC_TwoDimWriter*)m_pBCWriter)->RenderResult(data, outWidth, outHeight, e); + FX_Free(data); + BC_EXCEPTION_CHECK_ReturnValue(e, FALSE); + return TRUE; +} +FX_BOOL CBC_DataMatrix::RenderDevice(CFX_RenderDevice* device, + const CFX_Matrix* matirx, + int32_t& e) { + ((CBC_TwoDimWriter*)m_pBCWriter)->RenderDeviceResult(device, matirx); + return TRUE; +} +FX_BOOL CBC_DataMatrix::RenderBitmap(CFX_DIBitmap*& pOutBitmap, int32_t& e) { + ((CBC_TwoDimWriter*)m_pBCWriter)->RenderBitmapResult(pOutBitmap, e); + BC_EXCEPTION_CHECK_ReturnValue(e, FALSE); + return TRUE; +} +CFX_WideString CBC_DataMatrix::Decode(uint8_t* buf, + int32_t width, + int32_t hight, + int32_t& e) { + CFX_WideString str; + return str; +} +CFX_WideString CBC_DataMatrix::Decode(CFX_DIBitmap* pBitmap, int32_t& e) { + CBC_BufferedImageLuminanceSource source(pBitmap); + CBC_GlobalHistogramBinarizer binarizer(&source); + CBC_BinaryBitmap bitmap(&binarizer); + CFX_ByteString retStr = m_pBCReader->Decode(&bitmap, 0, e); + BC_EXCEPTION_CHECK_ReturnValue(e, FX_WSTRC(L"")); + return CFX_WideString::FromUTF8(retStr, retStr.GetLength()); +} diff --git a/xfa/fxbarcode/BC_Binarizer.cpp b/xfa/fxbarcode/BC_Binarizer.cpp new file mode 100644 index 0000000000..d36d8fc59c --- /dev/null +++ b/xfa/fxbarcode/BC_Binarizer.cpp @@ -0,0 +1,34 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com +// Original code is licensed as follows: +/* + * Copyright 2009 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "xfa/fxbarcode/BC_Binarizer.h" +#include "xfa/fxbarcode/BC_LuminanceSource.h" +#include "xfa/fxbarcode/common/BC_CommonBitArray.h" +#include "xfa/fxbarcode/common/BC_CommonBitMatrix.h" + +CBC_Binarizer::CBC_Binarizer(CBC_LuminanceSource* source) { + m_source = source; +} +CBC_Binarizer::~CBC_Binarizer() {} +CBC_LuminanceSource* CBC_Binarizer::GetLuminanceSource() { + return m_source; +} diff --git a/xfa/fxbarcode/BC_Binarizer.h b/xfa/fxbarcode/BC_Binarizer.h new file mode 100644 index 0000000000..20be039211 --- /dev/null +++ b/xfa/fxbarcode/BC_Binarizer.h @@ -0,0 +1,30 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef XFA_FXBARCODE_BC_BINARIZER_H_ +#define XFA_FXBARCODE_BC_BINARIZER_H_ + +#include <cstdint> + +class CBC_LuminanceSource; +class CBC_CommonBitMatrix; +class CBC_CommonBitArray; + +class CBC_Binarizer { + public: + CBC_Binarizer(CBC_LuminanceSource* source); + virtual ~CBC_Binarizer(); + CBC_LuminanceSource* GetLuminanceSource(); + virtual CBC_CommonBitMatrix* GetBlackMatrix(int32_t& e) = 0; + virtual CBC_CommonBitArray* GetBlackRow(int32_t y, + CBC_CommonBitArray* row, + int32_t& e) = 0; + + private: + CBC_LuminanceSource* m_source; +}; + +#endif // XFA_FXBARCODE_BC_BINARIZER_H_ diff --git a/xfa/fxbarcode/BC_BinaryBitmap.cpp b/xfa/fxbarcode/BC_BinaryBitmap.cpp new file mode 100644 index 0000000000..ba08824efe --- /dev/null +++ b/xfa/fxbarcode/BC_BinaryBitmap.cpp @@ -0,0 +1,61 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com +// Original code is licensed as follows: +/* + * Copyright 2009 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "xfa/fxbarcode/BC_Binarizer.h" +#include "xfa/fxbarcode/BC_BinaryBitmap.h" +#include "xfa/fxbarcode/BC_LuminanceSource.h" +#include "xfa/fxbarcode/common/BC_CommonBitArray.h" +#include "xfa/fxbarcode/common/BC_CommonBitMatrix.h" +#include "xfa/fxbarcode/utils.h" + +CBC_BinaryBitmap::CBC_BinaryBitmap(CBC_Binarizer* binarizer) + : m_binarizer(binarizer), m_matrix(NULL) {} +CBC_BinaryBitmap::~CBC_BinaryBitmap() { + delete m_matrix; +} +int32_t CBC_BinaryBitmap::GetHeight() { + return m_binarizer->GetLuminanceSource()->GetHeight(); +} +int32_t CBC_BinaryBitmap::GetWidth() { + return m_binarizer->GetLuminanceSource()->GetWidth(); +} +CBC_CommonBitMatrix* CBC_BinaryBitmap::GetMatrix(int32_t& e) { + if (m_matrix == NULL) { + m_matrix = m_binarizer->GetBlackMatrix(e); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + } + return m_matrix; +} +CBC_CommonBitArray* CBC_BinaryBitmap::GetBlackRow(int32_t y, + CBC_CommonBitArray* row, + int32_t& e) { + CBC_CommonBitArray* temp = m_binarizer->GetBlackRow(y, row, e); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + return temp; +} +CBC_CommonBitMatrix* CBC_BinaryBitmap::GetBlackMatrix(int32_t& e) { + if (m_matrix == NULL) { + m_matrix = m_binarizer->GetBlackMatrix(e); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + } + return m_matrix; +} diff --git a/xfa/fxbarcode/BC_BinaryBitmap.h b/xfa/fxbarcode/BC_BinaryBitmap.h new file mode 100644 index 0000000000..5f4dd874a9 --- /dev/null +++ b/xfa/fxbarcode/BC_BinaryBitmap.h @@ -0,0 +1,33 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef XFA_FXBARCODE_BC_BINARYBITMAP_H_ +#define XFA_FXBARCODE_BC_BINARYBITMAP_H_ + +#include <cstdint> + +class CBC_Binarizer; +class CBC_CommonBitMatrix; +class CBC_CommonBitArray; + +class CBC_BinaryBitmap { + public: + CBC_BinaryBitmap(CBC_Binarizer* binarizer); + virtual ~CBC_BinaryBitmap(); + int32_t GetWidth(); + int32_t GetHeight(); + CBC_CommonBitMatrix* GetMatrix(int32_t& e); + CBC_CommonBitArray* GetBlackRow(int32_t y, + CBC_CommonBitArray* row, + int32_t& e); + CBC_CommonBitMatrix* GetBlackMatrix(int32_t& e); + + private: + CBC_Binarizer* m_binarizer; + CBC_CommonBitMatrix* m_matrix; +}; + +#endif // XFA_FXBARCODE_BC_BINARYBITMAP_H_ diff --git a/xfa/fxbarcode/BC_BufferedImageLuminanceSource.cpp b/xfa/fxbarcode/BC_BufferedImageLuminanceSource.cpp new file mode 100644 index 0000000000..86b19c15af --- /dev/null +++ b/xfa/fxbarcode/BC_BufferedImageLuminanceSource.cpp @@ -0,0 +1,171 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com +// Original code is licensed as follows: +/* + * Copyright 2009 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "core/include/fxcodec/fx_codec.h" +#include "xfa/fxbarcode/BC_BufferedImageLuminanceSource.h" +#include "xfa/fxbarcode/BC_LuminanceSource.h" +#include "xfa/fxbarcode/utils.h" + +class CBC_Pause : public IFX_Pause { + public: + virtual FX_BOOL NeedToPauseNow() { return TRUE; } +}; +static CFX_DIBitmap* CreateDIBSource(IFX_FileRead* fileread) { + CFX_DIBitmap* bitmap = NULL; + CCodec_ModuleMgr* pCodecMgr = NULL; + ICodec_ProgressiveDecoder* pImageCodec = NULL; + pCodecMgr = new CCodec_ModuleMgr(); + pImageCodec = pCodecMgr->CreateProgressiveDecoder(); + FXCODEC_STATUS status = FXCODEC_STATUS_DECODE_FINISH; + status = pImageCodec->LoadImageInfo(fileread, FXCODEC_IMAGE_UNKNOWN, nullptr); + if (status != FXCODEC_STATUS_FRAME_READY) { + return NULL; + } + bitmap = new CFX_DIBitmap; + bitmap->Create(pImageCodec->GetWidth(), pImageCodec->GetHeight(), FXDIB_Argb); + bitmap->Clear(FXARGB_MAKE(0xFF, 0xFF, 0xFF, 0xFF)); + CBC_Pause pause; + int32_t frames; + status = pImageCodec->GetFrames(frames, &pause); + while (status == FXCODEC_STATUS_FRAME_TOBECONTINUE) { + status = pImageCodec->GetFrames(frames, &pause); + } + if (status != FXCODEC_STATUS_DECODE_READY) { + goto except; + } + status = pImageCodec->StartDecode(bitmap, 0, 0, bitmap->GetWidth(), + bitmap->GetHeight(), 0, FALSE); + if (status == FXCODEC_STATUS_ERR_PARAMS) { + goto except; + } + if (status != FXCODEC_STATUS_DECODE_TOBECONTINUE) { + goto except; + } + while (status == FXCODEC_STATUS_DECODE_TOBECONTINUE) { + status = pImageCodec->ContinueDecode(&pause); + } + if (status != FXCODEC_STATUS_DECODE_FINISH) { + goto except; + } + if (pImageCodec) { + delete pImageCodec; + pImageCodec = NULL; + } + delete pCodecMgr; + pCodecMgr = NULL; + return bitmap; +except: + if (pImageCodec) { + delete pImageCodec; + pImageCodec = NULL; + } + delete pCodecMgr; + pCodecMgr = NULL; + if (bitmap) { + delete bitmap; + } + return NULL; +} +CBC_BufferedImageLuminanceSource::CBC_BufferedImageLuminanceSource( + const CFX_WideString& filename) + : CBC_LuminanceSource(0, 0), m_filename(filename) { + m_height = 0; + m_width = 0; + m_bytesPerLine = 0; + m_top = 0; + m_left = 0; +} +void CBC_BufferedImageLuminanceSource::Init(int32_t& e) { + IFX_FileRead* fileread = FX_CreateFileRead(m_filename); + m_pBitmap = CreateDIBSource(fileread); + if (m_pBitmap == NULL) { + e = BCExceptionLoadFile; + return; + } + m_pBitmap->ConvertFormat(FXDIB_Argb); + m_height = m_pBitmap->GetHeight(); + m_width = m_pBitmap->GetWidth(); + m_rgbData.SetSize(m_height * m_width); + m_bytesPerLine = m_width * 4; + m_top = 0; + m_left = 0; +} +CBC_BufferedImageLuminanceSource::CBC_BufferedImageLuminanceSource( + CFX_DIBitmap* pBitmap) + : CBC_LuminanceSource(0, 0) { + m_pBitmap = pBitmap->Clone(); + m_pBitmap->ConvertFormat(FXDIB_Argb); + m_height = m_pBitmap->GetHeight(); + m_width = m_pBitmap->GetWidth(); + m_rgbData.SetSize(m_height * m_width); + m_bytesPerLine = m_width * 4; + m_top = 0; + m_left = 0; +} +CBC_BufferedImageLuminanceSource::~CBC_BufferedImageLuminanceSource() { + delete m_pBitmap; + m_pBitmap = NULL; +} +CFX_ByteArray* CBC_BufferedImageLuminanceSource::GetRow(int32_t y, + CFX_ByteArray& row, + int32_t& e) { + if (y < 0 || y >= m_height) { + e = BCExceptionRequestedRowIsOutSizeTheImage; + return NULL; + } + int32_t width = m_width; + if (row.GetSize() == 0 || row.GetSize() < width) { + row.SetSize(width); + } + if (m_rgbData.GetSize() == 0 || m_rgbData.GetSize() < width) { + m_rgbData.SetSize(width); + } + int32_t* rowLine = (int32_t*)m_pBitmap->GetScanline(y); + int32_t x; + for (x = 0; x < width; x++) { + int32_t pixel = rowLine[x]; + int32_t luminance = (306 * ((pixel >> 16) & 0xFF) + + 601 * ((pixel >> 8) & 0xFF) + 117 * (pixel & 0xFF)) >> + 10; + row[x] = (uint8_t)luminance; + } + return &row; +} +CFX_ByteArray* CBC_BufferedImageLuminanceSource::GetMatrix() { + CFX_ByteArray* matirx = new CFX_ByteArray(); + matirx->SetSize(m_bytesPerLine * m_height); + int32_t* rgb = (int32_t*)m_pBitmap->GetBuffer(); + int32_t y; + for (y = 0; y < m_height; y++) { + int32_t offset = y * m_width; + int32_t x; + for (x = 0; x < m_width; x++) { + int32_t pixel = rgb[offset + x]; + int32_t luminance = + (306 * ((pixel >> 16) & 0xFF) + 601 * ((pixel >> 8) & 0xFF) + + 117 * (pixel & 0xFF)) >> + 10; + (*matirx)[offset + x] = (uint8_t)luminance; + } + } + return matirx; +} diff --git a/xfa/fxbarcode/BC_BufferedImageLuminanceSource.h b/xfa/fxbarcode/BC_BufferedImageLuminanceSource.h new file mode 100644 index 0000000000..e39f4d638c --- /dev/null +++ b/xfa/fxbarcode/BC_BufferedImageLuminanceSource.h @@ -0,0 +1,34 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef XFA_FXBARCODE_BC_BUFFEREDIMAGELUMINANCESOURCE_H_ +#define XFA_FXBARCODE_BC_BUFFEREDIMAGELUMINANCESOURCE_H_ + +#include "core/include/fxcrt/fx_basic.h" +#include "core/include/fxcrt/fx_string.h" +#include "core/include/fxge/fx_dib.h" +#include "xfa/fxbarcode/BC_LuminanceSource.h" + +class CBC_BufferedImageLuminanceSource : public CBC_LuminanceSource { + public: + explicit CBC_BufferedImageLuminanceSource(const CFX_WideString& filename); + explicit CBC_BufferedImageLuminanceSource(CFX_DIBitmap* pBitmap); + virtual ~CBC_BufferedImageLuminanceSource(); + + CFX_ByteArray* GetRow(int32_t y, CFX_ByteArray& row, int32_t& e); + CFX_ByteArray* GetMatrix(); + virtual void Init(int32_t& e); + + private: + int32_t m_bytesPerLine; + int32_t m_left; + int32_t m_top; + CFX_Int32Array m_rgbData; + CFX_DIBitmap* m_pBitmap; + const CFX_WideString m_filename; +}; + +#endif // XFA_FXBARCODE_BC_BUFFEREDIMAGELUMINANCESOURCE_H_ diff --git a/xfa/fxbarcode/BC_DecoderResult.h b/xfa/fxbarcode/BC_DecoderResult.h new file mode 100644 index 0000000000..c3008c52bf --- /dev/null +++ b/xfa/fxbarcode/BC_DecoderResult.h @@ -0,0 +1,37 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef XFA_FXBARCODE_BC_DECODERRESULT_H_ +#define XFA_FXBARCODE_BC_DECODERRESULT_H_ + +#include "core/include/fxcrt/fx_basic.h" + +class CBC_DecoderResult { + public: + CBC_DecoderResult(CFX_ByteArray* rawBytes, + CFX_ByteString text, + CFX_ByteString ecLevel); + virtual ~CBC_DecoderResult(); + CFX_ByteArray* getRawBytes(); + CFX_ByteString getText(); + CFX_ByteString getECLevel(); + int32_t getErrorsCorrected(); + void setErrorsCorrected(int32_t errorsCorrected); + int32_t getErasures(); + void setErasures(int32_t erasures); + void* getOther(); + void setOther(void* other); + + private: + CFX_ByteArray* m_rawBytes; + CFX_ByteString m_text; + CFX_ByteString m_ecLevel; + int32_t m_errorsCorrected; + int32_t m_erasures; + void* m_other; +}; + +#endif // XFA_FXBARCODE_BC_DECODERRESULT_H_ diff --git a/xfa/fxbarcode/BC_Dimension.cpp b/xfa/fxbarcode/BC_Dimension.cpp new file mode 100644 index 0000000000..0cb076ce22 --- /dev/null +++ b/xfa/fxbarcode/BC_Dimension.cpp @@ -0,0 +1,46 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com +// Original code is licensed as follows: +/* + * Copyright 2012 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "xfa/fxbarcode/BC_Dimension.h" +#include "xfa/fxbarcode/datamatrix/BC_Encoder.h" + +CBC_Dimension::CBC_Dimension() {} +CBC_Dimension::CBC_Dimension(int32_t width, int32_t height, int32_t& e) { + if (width < 0 || height < 0) { + e = BCExceptionHeightAndWidthMustBeAtLeast1; + } + m_width = width; + m_height = height; +} +CBC_Dimension::~CBC_Dimension() {} +int32_t CBC_Dimension::getWidth() { + return m_width; +} +int32_t CBC_Dimension::getHeight() { + return m_height; +} +int32_t CBC_Dimension::hashCode() { + return m_width * 32713 + m_height; +} +CFX_WideString CBC_Dimension::toString() { + return (FX_WCHAR)(m_width + (FX_WCHAR)'x' + m_height); +} diff --git a/xfa/fxbarcode/BC_Dimension.h b/xfa/fxbarcode/BC_Dimension.h new file mode 100644 index 0000000000..e3253b38ad --- /dev/null +++ b/xfa/fxbarcode/BC_Dimension.h @@ -0,0 +1,29 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef XFA_FXBARCODE_BC_DIMENSION_H_ +#define XFA_FXBARCODE_BC_DIMENSION_H_ + +#include <cstdint> + +#include "core/include/fxcrt/fx_string.h" + +class CBC_Dimension { + public: + CBC_Dimension(); + CBC_Dimension(int32_t width, int32_t height, int32_t& e); + virtual ~CBC_Dimension(); + int32_t getWidth(); + int32_t getHeight(); + int32_t hashCode(); + CFX_WideString toString(); + + private: + int32_t m_width; + int32_t m_height; +}; + +#endif // XFA_FXBARCODE_BC_DIMENSION_H_ diff --git a/xfa/fxbarcode/BC_Library.cpp b/xfa/fxbarcode/BC_Library.cpp new file mode 100644 index 0000000000..d6da15cd29 --- /dev/null +++ b/xfa/fxbarcode/BC_Library.cpp @@ -0,0 +1,121 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#include "xfa/fxbarcode/BC_Binarizer.h" +#include "xfa/fxbarcode/BC_BinaryBitmap.h" +#include "xfa/fxbarcode/BC_BinaryBitmap.h" +#include "xfa/fxbarcode/BC_BufferedImageLuminanceSource.h" +#include "xfa/fxbarcode/BC_DecoderResult.h" +#include "xfa/fxbarcode/BC_Dimension.h" +#include "xfa/fxbarcode/BC_LuminanceSource.h" +#include "xfa/fxbarcode/BC_Reader.h" +#include "xfa/fxbarcode/BC_ResultPoint.h" +#include "xfa/fxbarcode/BC_TwoDimWriter.h" +#include "xfa/fxbarcode/BC_UtilCodingConvert.h" +#include "xfa/fxbarcode/BC_UtilCodingConvert.h" +#include "xfa/fxbarcode/BC_Writer.h" +#include "xfa/fxbarcode/common/BC_CommonBitArray.h" +#include "xfa/fxbarcode/common/BC_CommonBitMatrix.h" +#include "xfa/fxbarcode/common/BC_CommonBitMatrix.h" +#include "xfa/fxbarcode/common/BC_CommonBitMatrix.h" +#include "xfa/fxbarcode/common/BC_CommonByteMatrix.h" +#include "xfa/fxbarcode/common/BC_CommonDecoderResult.h" +#include "xfa/fxbarcode/common/BC_GlobalHistogramBinarizer.h" +#include "xfa/fxbarcode/common/reedsolomon/BC_ReedSolomonGF256.h" +#include "xfa/fxbarcode/datamatrix/BC_ASCIIEncoder.h" +#include "xfa/fxbarcode/datamatrix/BC_Base256Encoder.h" +#include "xfa/fxbarcode/datamatrix/BC_C40Encoder.h" +#include "xfa/fxbarcode/datamatrix/BC_DataMatrixReader.h" +#include "xfa/fxbarcode/datamatrix/BC_DataMatrixSymbolInfo144.h" +#include "xfa/fxbarcode/datamatrix/BC_DataMatrixVersion.h" +#include "xfa/fxbarcode/datamatrix/BC_DataMatrixWriter.h" +#include "xfa/fxbarcode/datamatrix/BC_DefaultPlacement.h" +#include "xfa/fxbarcode/datamatrix/BC_EdifactEncoder.h" +#include "xfa/fxbarcode/datamatrix/BC_Encoder.h" +#include "xfa/fxbarcode/datamatrix/BC_EncoderContext.h" +#include "xfa/fxbarcode/datamatrix/BC_ErrorCorrection.h" +#include "xfa/fxbarcode/datamatrix/BC_HighLevelEncoder.h" +#include "xfa/fxbarcode/datamatrix/BC_SymbolInfo.h" +#include "xfa/fxbarcode/datamatrix/BC_SymbolShapeHint.h" +#include "xfa/fxbarcode/datamatrix/BC_TextEncoder.h" +#include "xfa/fxbarcode/datamatrix/BC_X12Encoder.h" +#include "xfa/fxbarcode/oned/BC_OneDReader.h" +#include "xfa/fxbarcode/oned/BC_OneDimReader.h" +#include "xfa/fxbarcode/oned/BC_OneDimWriter.h" +#include "xfa/fxbarcode/oned/BC_OnedCodaBarReader.h" +#include "xfa/fxbarcode/oned/BC_OnedCode128Reader.h" +#include "xfa/fxbarcode/oned/BC_OnedCode128Writer.h" +#include "xfa/fxbarcode/oned/BC_OnedCode39Reader.h" +#include "xfa/fxbarcode/oned/BC_OnedCode39Writer.h" +#include "xfa/fxbarcode/oned/BC_OnedEAN13Reader.h" +#include "xfa/fxbarcode/oned/BC_OnedEAN13Writer.h" +#include "xfa/fxbarcode/oned/BC_OnedEAN8Reader.h" +#include "xfa/fxbarcode/oned/BC_OnedEAN8Writer.h" +#include "xfa/fxbarcode/oned/BC_OnedUPCAReader.h" +#include "xfa/fxbarcode/oned/BC_OnedUPCAWriter.h" +#include "xfa/fxbarcode/pdf417/BC_PDF417BarcodeMetadata.h" +#include "xfa/fxbarcode/pdf417/BC_PDF417BarcodeValue.h" +#include "xfa/fxbarcode/pdf417/BC_PDF417BoundingBox.h" +#include "xfa/fxbarcode/pdf417/BC_PDF417Codeword.h" +#include "xfa/fxbarcode/pdf417/BC_PDF417CodewordDecoder.h" +#include "xfa/fxbarcode/pdf417/BC_PDF417Common.h" +#include "xfa/fxbarcode/pdf417/BC_PDF417Compaction.h" +#include "xfa/fxbarcode/pdf417/BC_PDF417DecodedBitStreamParser.h" +#include "xfa/fxbarcode/pdf417/BC_PDF417DecodedBitStreamParser.h" +#include "xfa/fxbarcode/pdf417/BC_PDF417DecodedBitStreamParser.h" +#include "xfa/fxbarcode/pdf417/BC_PDF417DetectionResult.h" +#include "xfa/fxbarcode/pdf417/BC_PDF417DetectionResultColumn.h" +#include "xfa/fxbarcode/pdf417/BC_PDF417DetectionResultRowIndicatorColumn.h" +#include "xfa/fxbarcode/pdf417/BC_PDF417Detector.h" +#include "xfa/fxbarcode/pdf417/BC_PDF417DetectorResult.h" +#include "xfa/fxbarcode/pdf417/BC_PDF417DetectorResult.h" +#include "xfa/fxbarcode/pdf417/BC_PDF417ECErrorCorrection.h" +#include "xfa/fxbarcode/pdf417/BC_PDF417ECModulusGF.h" +#include "xfa/fxbarcode/pdf417/BC_PDF417ECModulusPoly.h" +#include "xfa/fxbarcode/pdf417/BC_PDF417HighLevelEncoder.h" +#include "xfa/fxbarcode/pdf417/BC_PDF417Reader.h" +#include "xfa/fxbarcode/pdf417/BC_PDF417ScanningDecoder.h" +#include "xfa/fxbarcode/qrcode/BC_QRCodeReader.h" +#include "xfa/fxbarcode/qrcode/BC_QRCodeWriter.h" +#include "xfa/fxbarcode/qrcode/BC_QRCoderErrorCorrectionLevel.h" +#include "xfa/fxbarcode/qrcode/BC_QRCoderMode.h" +#include "xfa/fxbarcode/qrcode/BC_QRCoderVersion.h" +#include "xfa/fxbarcode/qrcode/BC_QRDataMask.h" +#include "xfa/fxbarcode/qrcode/BC_QRDecodedBitStreamParser.h" + +void BC_Library_Init() { + CBC_QRCoderErrorCorrectionLevel::Initialize(); + CBC_QRCoderMode::Initialize(); + CBC_QRCoderVersion::Initialize(); + CBC_QRDataMask::Initialize(); + CBC_ReedSolomonGF256::Initialize(); + CBC_DataMatrixVersion::Initialize(); + CBC_SymbolInfo::Initialize(); + CBC_ErrorCorrection::Initialize(); + CBC_PDF417HighLevelEncoder::Initialize(); + int32_t e = 0; + CBC_PDF417ECModulusGF::Initialize(e); + CBC_DecodedBitStreamPaser::Initialize(); + CBC_PDF417CodewordDecoder::Initialize(); + CBC_PDF417ECErrorCorrection::Initialize(e); + CBC_PDF417ScanningDecoder::Initialize(); +} +void BC_Library_Destory() { + CBC_QRCoderErrorCorrectionLevel::Finalize(); + CBC_QRCoderMode::Finalize(); + CBC_QRCoderVersion::Finalize(); + CBC_QRDataMask::Finalize(); + CBC_ReedSolomonGF256::Finalize(); + CBC_DataMatrixVersion::Finalize(); + CBC_SymbolInfo::Finalize(); + CBC_ErrorCorrection::Finalize(); + CBC_PDF417HighLevelEncoder::Finalize(); + CBC_DecodedBitStreamPaser::Finalize(); + CBC_PDF417CodewordDecoder::Finalize(); + CBC_PDF417ECErrorCorrection::Finalize(); + CBC_PDF417ECModulusGF::Finalize(); + CBC_PDF417ScanningDecoder::Finalize(); +} diff --git a/xfa/fxbarcode/BC_LuminanceSource.cpp b/xfa/fxbarcode/BC_LuminanceSource.cpp new file mode 100644 index 0000000000..0aaa096197 --- /dev/null +++ b/xfa/fxbarcode/BC_LuminanceSource.cpp @@ -0,0 +1,33 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com +// Original code is licensed as follows: +/* + * Copyright 2009 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "xfa/fxbarcode/BC_LuminanceSource.h" + +CBC_LuminanceSource::CBC_LuminanceSource(int32_t width, int32_t height) + : m_width(width), m_height(height) {} +CBC_LuminanceSource::~CBC_LuminanceSource() {} +int32_t CBC_LuminanceSource::GetWidth() { + return m_width; +} +int32_t CBC_LuminanceSource::GetHeight() { + return m_height; +} diff --git a/xfa/fxbarcode/BC_LuminanceSource.h b/xfa/fxbarcode/BC_LuminanceSource.h new file mode 100644 index 0000000000..b4b3ebc03c --- /dev/null +++ b/xfa/fxbarcode/BC_LuminanceSource.h @@ -0,0 +1,27 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef XFA_FXBARCODE_BC_LUMINANCESOURCE_H_ +#define XFA_FXBARCODE_BC_LUMINANCESOURCE_H_ + +#include "core/include/fxcrt/fx_basic.h" + +class CBC_LuminanceSource { + public: + CBC_LuminanceSource(int32_t width, int32_t height); + virtual ~CBC_LuminanceSource(); + int32_t GetWidth(); + int32_t GetHeight(); + + virtual CFX_ByteArray* GetRow(int32_t y, CFX_ByteArray& row, int32_t& e) = 0; + virtual CFX_ByteArray* GetMatrix() = 0; + + protected: + int32_t m_width; + int32_t m_height; +}; + +#endif // XFA_FXBARCODE_BC_LUMINANCESOURCE_H_ diff --git a/xfa/fxbarcode/BC_Reader.cpp b/xfa/fxbarcode/BC_Reader.cpp new file mode 100644 index 0000000000..9391da1856 --- /dev/null +++ b/xfa/fxbarcode/BC_Reader.cpp @@ -0,0 +1,10 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#include "xfa/fxbarcode/BC_Reader.h" + +CBC_Reader::CBC_Reader() {} +CBC_Reader::~CBC_Reader() {} diff --git a/xfa/fxbarcode/BC_Reader.h b/xfa/fxbarcode/BC_Reader.h new file mode 100644 index 0000000000..12cfd243e5 --- /dev/null +++ b/xfa/fxbarcode/BC_Reader.h @@ -0,0 +1,24 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef XFA_FXBARCODE_BC_READER_H_ +#define XFA_FXBARCODE_BC_READER_H_ + +#include "core/include/fxcrt/fx_string.h" + +class CBC_BinaryBitmap; + +class CBC_Reader { + public: + CBC_Reader(); + virtual ~CBC_Reader(); + virtual CFX_ByteString Decode(CBC_BinaryBitmap* image, int32_t& e) = 0; + virtual CFX_ByteString Decode(CBC_BinaryBitmap* image, + int32_t hints, + int32_t& e) = 0; +}; + +#endif // XFA_FXBARCODE_BC_READER_H_ diff --git a/xfa/fxbarcode/BC_ResultPoint.cpp b/xfa/fxbarcode/BC_ResultPoint.cpp new file mode 100644 index 0000000000..9726ea4240 --- /dev/null +++ b/xfa/fxbarcode/BC_ResultPoint.cpp @@ -0,0 +1,31 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com +// Original code is licensed as follows: +/* + * Copyright 2007 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "xfa/fxbarcode/BC_ResultPoint.h" + +CBC_ResultPoint::CBC_ResultPoint(FX_FLOAT x, FX_FLOAT y) : m_x(x), m_y(y) {} +FX_FLOAT CBC_ResultPoint::GetX() { + return m_x; +} +FX_FLOAT CBC_ResultPoint::GetY() { + return m_y; +} diff --git a/xfa/fxbarcode/BC_ResultPoint.h b/xfa/fxbarcode/BC_ResultPoint.h new file mode 100644 index 0000000000..721adb1eaa --- /dev/null +++ b/xfa/fxbarcode/BC_ResultPoint.h @@ -0,0 +1,25 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef XFA_FXBARCODE_BC_RESULTPOINT_H_ +#define XFA_FXBARCODE_BC_RESULTPOINT_H_ + +#include "core/include/fxcrt/fx_system.h" + +class CBC_ResultPoint { + public: + CBC_ResultPoint(); + CBC_ResultPoint(FX_FLOAT x, FX_FLOAT y); + virtual ~CBC_ResultPoint() {} + virtual FX_FLOAT GetX(); + virtual FX_FLOAT GetY(); + + protected: + FX_FLOAT m_x; + FX_FLOAT m_y; +}; + +#endif // XFA_FXBARCODE_BC_RESULTPOINT_H_ diff --git a/xfa/fxbarcode/BC_TwoDimWriter.cpp b/xfa/fxbarcode/BC_TwoDimWriter.cpp new file mode 100644 index 0000000000..f0065a02b9 --- /dev/null +++ b/xfa/fxbarcode/BC_TwoDimWriter.cpp @@ -0,0 +1,148 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#include <algorithm> + +#include "third_party/base/numerics/safe_math.h" +#include "xfa/fxbarcode/BC_TwoDimWriter.h" +#include "xfa/fxbarcode/BC_Writer.h" +#include "xfa/fxbarcode/common/BC_CommonBitMatrix.h" + +CBC_TwoDimWriter::CBC_TwoDimWriter() { + m_iCorrectLevel = 1; + m_bFixedSize = TRUE; + m_output = NULL; +} +CBC_TwoDimWriter::~CBC_TwoDimWriter() { + delete m_output; +} +void CBC_TwoDimWriter::RenderDeviceResult(CFX_RenderDevice* device, + const CFX_Matrix* matrix) { + CFX_GraphStateData stateData; + CFX_PathData path; + path.AppendRect(0, 0, (FX_FLOAT)m_Width, (FX_FLOAT)m_Height); + device->DrawPath(&path, matrix, &stateData, m_backgroundColor, + m_backgroundColor, FXFILL_ALTERNATE); + int32_t leftPos = 0; + int32_t topPos = 0; + if (m_bFixedSize) { + leftPos = (m_Width - m_output->GetWidth()) / 2; + topPos = (m_Height - m_output->GetHeight()) / 2; + } + CFX_Matrix matri = *matrix; + if (m_Width < m_output->GetWidth() && m_Height < m_output->GetHeight()) { + CFX_Matrix matriScale( + (FX_FLOAT)m_Width / (FX_FLOAT)m_output->GetWidth(), 0.0, 0.0, + (FX_FLOAT)m_Height / (FX_FLOAT)m_output->GetHeight(), 0.0, 0.0); + matriScale.Concat(*matrix); + matri = matriScale; + } + for (int32_t x = 0; x < m_output->GetWidth(); x++) { + for (int32_t y = 0; y < m_output->GetHeight(); y++) { + CFX_PathData rect; + rect.AppendRect((FX_FLOAT)leftPos + x, (FX_FLOAT)topPos + y, + (FX_FLOAT)(leftPos + x + 1), (FX_FLOAT)(topPos + y + 1)); + CFX_GraphStateData stateData; + if (m_output->Get(x, y)) { + device->DrawPath(&rect, &matri, &stateData, m_barColor, 0, + FXFILL_WINDING); + } + } + } +} +void CBC_TwoDimWriter::RenderBitmapResult(CFX_DIBitmap*& pOutBitmap, + int32_t& e) { + if (m_bFixedSize) { + pOutBitmap = CreateDIBitmap(m_Width, m_Height); + } else { + pOutBitmap = CreateDIBitmap(m_output->GetWidth(), m_output->GetHeight()); + } + if (!pOutBitmap) { + e = BCExceptionFailToCreateBitmap; + return; + } + pOutBitmap->Clear(m_backgroundColor); + int32_t leftPos = 0; + int32_t topPos = 0; + if (m_bFixedSize) { + leftPos = (m_Width - m_output->GetWidth()) / 2; + topPos = (m_Height - m_output->GetHeight()) / 2; + } + for (int32_t x = 0; x < m_output->GetWidth(); x++) { + for (int32_t y = 0; y < m_output->GetHeight(); y++) { + if (m_output->Get(x, y)) { + pOutBitmap->SetPixel(leftPos + x, topPos + y, m_barColor); + } + } + } + if (!m_bFixedSize) { + CFX_DIBitmap* pStretchBitmap = pOutBitmap->StretchTo(m_Width, m_Height); + if (pOutBitmap) { + delete pOutBitmap; + } + pOutBitmap = pStretchBitmap; + } +} +void CBC_TwoDimWriter::RenderResult(uint8_t* code, + int32_t codeWidth, + int32_t codeHeight, + int32_t& e) { + int32_t inputWidth = codeWidth; + int32_t inputHeight = codeHeight; + int32_t tempWidth = inputWidth + 2; + int32_t tempHeight = inputHeight + 2; + FX_FLOAT moduleHSize = std::min(m_ModuleWidth, m_ModuleHeight); + moduleHSize = std::min(moduleHSize, 8.0f); + moduleHSize = std::max(moduleHSize, 1.0f); + pdfium::base::CheckedNumeric<int32_t> scaledWidth = tempWidth; + pdfium::base::CheckedNumeric<int32_t> scaledHeight = tempHeight; + scaledWidth *= moduleHSize; + scaledHeight *= moduleHSize; + + int32_t outputWidth = scaledWidth.ValueOrDie(); + int32_t outputHeight = scaledHeight.ValueOrDie(); + if (m_bFixedSize) { + if (m_Width < outputWidth || m_Height < outputHeight) { + e = BCExceptionBitmapSizeError; + return; + } + } else { + if (m_Width > outputWidth || m_Height > outputHeight) { + outputWidth = (int32_t)(outputWidth * + ceil((FX_FLOAT)m_Width / (FX_FLOAT)outputWidth)); + outputHeight = (int32_t)( + outputHeight * ceil((FX_FLOAT)m_Height / (FX_FLOAT)outputHeight)); + } + } + int32_t multiX = (int32_t)ceil((FX_FLOAT)outputWidth / (FX_FLOAT)tempWidth); + int32_t multiY = (int32_t)ceil((FX_FLOAT)outputHeight / (FX_FLOAT)tempHeight); + if (m_bFixedSize) { + multiX = std::min(multiX, multiY); + multiY = multiX; + } + int32_t leftPadding = (outputWidth - (inputWidth * multiX)) / 2; + int32_t topPadding = (outputHeight - (inputHeight * multiY)) / 2; + if (leftPadding < 0) { + leftPadding = 0; + } + if (topPadding < 0) { + topPadding = 0; + } + m_output = new CBC_CommonBitMatrix; + m_output->Init(outputWidth, outputHeight); + for (int32_t inputY = 0, outputY = topPadding; + (inputY < inputHeight) && (outputY < outputHeight - multiY); + inputY++, outputY += multiY) { + for (int32_t inputX = 0, outputX = leftPadding; + (inputX < inputWidth) && (outputX < outputWidth - multiX); + inputX++, outputX += multiX) { + if (code[inputX + inputY * inputWidth] == 1) { + m_output->SetRegion(outputX, outputY, multiX, multiY, e); + BC_EXCEPTION_CHECK_ReturnVoid(e); + } + } + } +} diff --git a/xfa/fxbarcode/BC_TwoDimWriter.h b/xfa/fxbarcode/BC_TwoDimWriter.h new file mode 100644 index 0000000000..f5dcd61ff8 --- /dev/null +++ b/xfa/fxbarcode/BC_TwoDimWriter.h @@ -0,0 +1,35 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef XFA_FXBARCODE_BC_TWODIMWRITER_H_ +#define XFA_FXBARCODE_BC_TWODIMWRITER_H_ + +#include "core/include/fxge/fx_ge.h" +#include "xfa/fxbarcode/BC_Writer.h" + +class CBC_CommonBitMatrix; + +class CBC_TwoDimWriter : public CBC_Writer { + public: + CBC_TwoDimWriter(); + virtual ~CBC_TwoDimWriter(); + virtual void RenderResult(uint8_t* code, + int32_t codeWidth, + int32_t codeHeight, + int32_t& e); + virtual void RenderBitmapResult(CFX_DIBitmap*& pOutBitmap, int32_t& e); + virtual void RenderDeviceResult(CFX_RenderDevice* device, + const CFX_Matrix* matrix); + virtual FX_BOOL SetErrorCorrectionLevel(int32_t level) = 0; + virtual int32_t GetErrorCorrectionLevel() { return m_iCorrectLevel; } + + protected: + int32_t m_iCorrectLevel; + FX_BOOL m_bFixedSize; + CBC_CommonBitMatrix* m_output; +}; + +#endif // XFA_FXBARCODE_BC_TWODIMWRITER_H_ diff --git a/xfa/fxbarcode/BC_UtilCodingConvert.cpp b/xfa/fxbarcode/BC_UtilCodingConvert.cpp new file mode 100644 index 0000000000..8421e280f3 --- /dev/null +++ b/xfa/fxbarcode/BC_UtilCodingConvert.cpp @@ -0,0 +1,53 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#include "xfa/fxbarcode/BC_UtilCodingConvert.h" + +CBC_UtilCodingConvert::CBC_UtilCodingConvert() {} + +CBC_UtilCodingConvert::~CBC_UtilCodingConvert() {} + +void CBC_UtilCodingConvert::UnicodeToLocale(const CFX_WideString& src, + CFX_ByteString& dst) { + dst = CFX_ByteString::FromUnicode(src); +} + +void CBC_UtilCodingConvert::LocaleToUtf8(const CFX_ByteString& src, + CFX_ByteString& dst) { + CFX_WideString unicode = CFX_WideString::FromLocal(src); + dst = unicode.UTF8Encode(); +} + +void CBC_UtilCodingConvert::LocaleToUtf8(const CFX_ByteString& src, + CFX_ByteArray& dst) { + CFX_WideString unicode = CFX_WideString::FromLocal(src); + CFX_ByteString utf8 = unicode.UTF8Encode(); + for (int32_t i = 0; i < utf8.GetLength(); i++) { + dst.Add(utf8[i]); + } +} + +void CBC_UtilCodingConvert::Utf8ToLocale(const CFX_ByteArray& src, + CFX_ByteString& dst) { + CFX_ByteString utf8; + for (int32_t i = 0; i < src.GetSize(); i++) { + utf8 += src[i]; + } + CFX_WideString unicode = CFX_WideString::FromUTF8(utf8, utf8.GetLength()); + dst = CFX_ByteString::FromUnicode(unicode); +} + +void CBC_UtilCodingConvert::Utf8ToLocale(const uint8_t* src, + int32_t count, + CFX_ByteString& dst) { + CFX_WideString unicode = CFX_WideString::FromUTF8((const char*)src, count); + dst = CFX_ByteString::FromUnicode(unicode); +} + +void CBC_UtilCodingConvert::UnicodeToUTF8(const CFX_WideString& src, + CFX_ByteString& dst) { + dst = src.UTF8Encode(); +} diff --git a/xfa/fxbarcode/BC_UtilCodingConvert.h b/xfa/fxbarcode/BC_UtilCodingConvert.h new file mode 100644 index 0000000000..2d5c9f3892 --- /dev/null +++ b/xfa/fxbarcode/BC_UtilCodingConvert.h @@ -0,0 +1,29 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef XFA_FXBARCODE_BC_UTILCODINGCONVERT_H_ +#define XFA_FXBARCODE_BC_UTILCODINGCONVERT_H_ + +#include "core/include/fxcrt/fx_basic.h" + +class CBC_UtilCodingConvert { + public: + CBC_UtilCodingConvert(); + virtual ~CBC_UtilCodingConvert(); + static void UnicodeToLocale(const CFX_WideString& source, + CFX_ByteString& result); + static void LocaleToUtf8(const CFX_ByteString& source, + CFX_ByteString& result); + static void LocaleToUtf8(const CFX_ByteString& source, CFX_ByteArray& result); + static void Utf8ToLocale(const CFX_ByteArray& source, CFX_ByteString& result); + static void Utf8ToLocale(const uint8_t* source, + int32_t count, + CFX_ByteString& result); + static void UnicodeToUTF8(const CFX_WideString& source, + CFX_ByteString& result); +}; + +#endif // XFA_FXBARCODE_BC_UTILCODINGCONVERT_H_ diff --git a/xfa/fxbarcode/BC_UtilRSS.cpp b/xfa/fxbarcode/BC_UtilRSS.cpp new file mode 100644 index 0000000000..0d6133cf40 --- /dev/null +++ b/xfa/fxbarcode/BC_UtilRSS.cpp @@ -0,0 +1,164 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com +// Original code is licensed as follows: +/* + * Copyright 2009 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "xfa/fxbarcode/BC_UtilRSS.h" + +#include <memory> + +#include "core/include/fxcrt/fx_basic.h" +#include "xfa/fxbarcode/utils.h" + +CBC_UtilRSS::CBC_UtilRSS() {} +CBC_UtilRSS::~CBC_UtilRSS() {} +CFX_Int32Array* CBC_UtilRSS::GetRssWidths(int32_t val, + int32_t n, + int32_t elements, + int32_t maxWidth, + FX_BOOL noNarrow) { + std::unique_ptr<CFX_Int32Array> widths(new CFX_Int32Array); + widths->SetSize(elements); + int32_t bar; + int32_t narrowMask = 0; + for (bar = 0; bar < elements - 1; bar++) { + narrowMask |= (1 << bar); + int32_t elmWidth = 1; + int32_t subVal; + while (TRUE) { + subVal = Combins(n - elmWidth - 1, elements - bar - 2); + if (noNarrow && (narrowMask == 0) && + (n - elmWidth - (elements - bar - 1) >= elements - bar - 1)) { + subVal -= Combins(n - elmWidth - (elements - bar), elements - bar - 2); + } + if (elements - bar - 1 > 1) { + int32_t lessVal = 0; + for (int32_t mxwElement = n - elmWidth - (elements - bar - 2); + mxwElement > maxWidth; mxwElement--) { + lessVal += Combins(n - elmWidth - mxwElement - 1, elements - bar - 3); + } + subVal -= lessVal * (elements - 1 - bar); + } else if (n - elmWidth > maxWidth) { + subVal--; + } + val -= subVal; + if (val < 0) { + break; + } + elmWidth++; + narrowMask &= ~(1 << bar); + } + val += subVal; + n -= elmWidth; + (*widths)[bar] = elmWidth; + } + (*widths)[bar] = n; + return widths.release(); +} +int32_t CBC_UtilRSS::GetRSSvalue(CFX_Int32Array& widths, + int32_t maxWidth, + FX_BOOL noNarrow) { + int32_t elements = widths.GetSize(); + int32_t n = 0; + for (int32_t i = 0; i < elements; i++) { + n += widths[i]; + } + int32_t val = 0; + int32_t narrowMask = 0; + for (int32_t bar = 0; bar < elements - 1; bar++) { + int32_t elmWidth; + for (elmWidth = 1, narrowMask |= (1 << bar); elmWidth < widths[bar]; + elmWidth++, narrowMask &= ~(1 << bar)) { + int32_t subVal = Combins(n - elmWidth - 1, elements - bar - 2); + if (noNarrow && (narrowMask == 0) && + (n - elmWidth - (elements - bar - 1) >= elements - bar - 1)) { + subVal -= Combins(n - elmWidth - (elements - bar), elements - bar - 2); + } + if (elements - bar - 1 > 1) { + int32_t lessVal = 0; + for (int32_t mxwElement = n - elmWidth - (elements - bar - 2); + mxwElement > maxWidth; mxwElement--) { + lessVal += Combins(n - elmWidth - mxwElement - 1, elements - bar - 3); + } + subVal -= lessVal * (elements - 1 - bar); + } else if (n - elmWidth > maxWidth) { + subVal--; + } + val += subVal; + } + n -= elmWidth; + } + return val; +} +int32_t CBC_UtilRSS::Combins(int32_t n, int32_t r) { + int32_t maxDenom; + int32_t minDenom; + if (n - r > r) { + minDenom = r; + maxDenom = n - r; + } else { + minDenom = n - r; + maxDenom = r; + } + int32_t val = 1; + int32_t j = 1; + for (int32_t i = n; i > maxDenom; i--) { + val *= i; + if (j <= minDenom) { + val /= j; + j++; + } + } + while (j <= minDenom) { + val /= j; + j++; + } + return val; +} +CFX_Int32Array* CBC_UtilRSS::Elements(CFX_Int32Array& eDist, + int32_t N, + int32_t K) { + CFX_Int32Array* widths = new CFX_Int32Array; + widths->SetSize(eDist.GetSize() + 2); + int32_t twoK = K << 1; + (*widths)[0] = 1; + int32_t i; + int32_t minEven = 10; + int32_t barSum = 1; + for (i = 1; i < twoK - 2; i += 2) { + (*widths)[i] = eDist[i - 1] - (*widths)[i - 1]; + (*widths)[i + 1] = eDist[i] - (*widths)[i]; + barSum += (*widths)[i] + (*widths)[i + 1]; + if ((*widths)[i] < minEven) { + minEven = (*widths)[i]; + } + } + (*widths)[twoK - 1] = N - barSum; + if ((*widths)[twoK - 1] < minEven) { + minEven = (*widths)[twoK - 1]; + } + if (minEven > 1) { + for (i = 0; i < twoK; i += 2) { + (*widths)[i] += minEven - 1; + (*widths)[i + 1] -= minEven - 1; + } + } + return widths; +} diff --git a/xfa/fxbarcode/BC_UtilRSS.h b/xfa/fxbarcode/BC_UtilRSS.h new file mode 100644 index 0000000000..b81804e0c8 --- /dev/null +++ b/xfa/fxbarcode/BC_UtilRSS.h @@ -0,0 +1,34 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef XFA_FXBARCODE_BC_UTILRSS_H_ +#define XFA_FXBARCODE_BC_UTILRSS_H_ + +#include <cstdint> + +#include "core/include/fxcrt/fx_basic.h" + +class CBC_UtilRSS { + public: + virtual ~CBC_UtilRSS(); + static int32_t GetRSSvalue(CFX_Int32Array& widths, + int32_t maxWidth, + FX_BOOL noNarrow); + + protected: + static CFX_Int32Array* GetRssWidths(int32_t val, + int32_t n, + int32_t elements, + int32_t maxWidth, + FX_BOOL noNarrow); + static int32_t Combins(int32_t n, int32_t r); + static CFX_Int32Array* Elements(CFX_Int32Array& eDist, int32_t N, int32_t K); + + private: + CBC_UtilRSS(); +}; + +#endif // XFA_FXBARCODE_BC_UTILRSS_H_ diff --git a/xfa/fxbarcode/BC_Utils.cpp b/xfa/fxbarcode/BC_Utils.cpp new file mode 100644 index 0000000000..02719689e6 --- /dev/null +++ b/xfa/fxbarcode/BC_Utils.cpp @@ -0,0 +1,48 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#include "core/include/fxcrt/fx_basic.h" +#include "xfa/fxbarcode/utils.h" + +FX_BOOL BC_FX_ByteString_Replace(CFX_ByteString& dst, + FX_DWORD first, + FX_DWORD last, + int32_t count, + FX_CHAR c) { + if (first > last || count <= 0) { + return FALSE; + } + dst.Delete(first, last - first); + for (int32_t i = 0; i < count; i++) { + dst.Insert(0, c); + } + return TRUE; +} +void BC_FX_ByteString_Append(CFX_ByteString& dst, int32_t count, FX_CHAR c) { + for (int32_t i = 0; i < count; i++) { + dst += c; + } +} +void BC_FX_ByteString_Append(CFX_ByteString& dst, const CFX_ByteArray& ba) { + for (int32_t i = 0; i < ba.GetSize(); i++) { + dst += ba[i]; + } +} +void BC_FX_PtrArray_Sort(CFX_PtrArray& src, BC_PtrArrayCompareCallback fun) { + int32_t nLength = src.GetSize(); + FX_BOOL changed = true; + do { + changed = false; + for (int32_t i = 0; i < nLength - 1; i++) { + if (fun(src[i + 1], src[i])) { + void* temp = src[i]; + src.SetAt(i, src[i + 1]); + src.SetAt(i + 1, temp); + changed = true; + } + } + } while (changed); +} diff --git a/xfa/fxbarcode/BC_Writer.cpp b/xfa/fxbarcode/BC_Writer.cpp new file mode 100644 index 0000000000..835a2f0309 --- /dev/null +++ b/xfa/fxbarcode/BC_Writer.cpp @@ -0,0 +1,56 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#include "xfa/fxbarcode/BC_Writer.h" + +CBC_Writer::CBC_Writer() { + m_CharEncoding = 0; + m_ModuleHeight = 1; + m_ModuleWidth = 1; + m_Height = 320; + m_Width = 640; + m_colorSpace = FXDIB_Argb; + m_barColor = 0xff000000; + m_backgroundColor = 0xffffffff; +} +CBC_Writer::~CBC_Writer() {} +FX_BOOL CBC_Writer::SetCharEncoding(int32_t encoding) { + m_CharEncoding = encoding; + return TRUE; +} +FX_BOOL CBC_Writer::SetModuleHeight(int32_t moduleHeight) { + if (moduleHeight > 10 || moduleHeight < 1) { + return FALSE; + } + m_ModuleHeight = moduleHeight; + return TRUE; +} +FX_BOOL CBC_Writer::SetModuleWidth(int32_t moduleWidth) { + if (moduleWidth > 10 || moduleWidth < 1) { + return FALSE; + } + m_ModuleWidth = moduleWidth; + return TRUE; +} +FX_BOOL CBC_Writer::SetHeight(int32_t height) { + m_Height = height; + return TRUE; +} +FX_BOOL CBC_Writer::SetWidth(int32_t width) { + m_Width = width; + return TRUE; +} +void CBC_Writer::SetBackgroundColor(FX_ARGB backgroundColor) { + m_backgroundColor = backgroundColor; +} +void CBC_Writer::SetBarcodeColor(FX_ARGB foregroundColor) { + m_barColor = foregroundColor; +} +CFX_DIBitmap* CBC_Writer::CreateDIBitmap(int32_t width, int32_t height) { + CFX_DIBitmap* pDIBitmap = new CFX_DIBitmap; + pDIBitmap->Create(width, height, m_colorSpace); + return pDIBitmap; +} diff --git a/xfa/fxbarcode/BC_Writer.h b/xfa/fxbarcode/BC_Writer.h new file mode 100644 index 0000000000..bff3642b94 --- /dev/null +++ b/xfa/fxbarcode/BC_Writer.h @@ -0,0 +1,38 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef XFA_FXBARCODE_BC_WRITER_H_ +#define XFA_FXBARCODE_BC_WRITER_H_ + +#include "core/include/fxcrt/fx_string.h" +#include "core/include/fxge/fx_dib.h" +#include "xfa/fxbarcode/utils.h" + +class CBC_Writer { + public: + CBC_Writer(); + virtual ~CBC_Writer(); + virtual FX_BOOL SetCharEncoding(int32_t encoding); + virtual FX_BOOL SetModuleHeight(int32_t moduleHeight); + virtual FX_BOOL SetModuleWidth(int32_t moduleWidth); + virtual FX_BOOL SetHeight(int32_t height); + virtual FX_BOOL SetWidth(int32_t width); + virtual void SetBackgroundColor(FX_ARGB backgroundColor); + virtual void SetBarcodeColor(FX_ARGB foregroundColor); + + protected: + CFX_DIBitmap* CreateDIBitmap(int32_t width, int32_t height); + int32_t m_CharEncoding; + int32_t m_ModuleHeight; + int32_t m_ModuleWidth; + int32_t m_Height; + int32_t m_Width; + FXDIB_Format m_colorSpace; + FX_ARGB m_barColor; + FX_ARGB m_backgroundColor; +}; + +#endif // XFA_FXBARCODE_BC_WRITER_H_ diff --git a/xfa/fxbarcode/common/BC_CommonBitArray.cpp b/xfa/fxbarcode/common/BC_CommonBitArray.cpp new file mode 100644 index 0000000000..b39e4acd88 --- /dev/null +++ b/xfa/fxbarcode/common/BC_CommonBitArray.cpp @@ -0,0 +1,113 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com +// Original code is licensed as follows: +/* + * Copyright 2007 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "xfa/fxbarcode/common/BC_CommonBitArray.h" +#include "xfa/fxbarcode/utils.h" + +CBC_CommonBitArray::CBC_CommonBitArray(CBC_CommonBitArray* array) { + m_size = array->GetSize(); + m_bits.Copy(array->GetBits()); +} +CBC_CommonBitArray::CBC_CommonBitArray() { + m_bits.SetSize(1); + m_size = 0; +} +CBC_CommonBitArray::CBC_CommonBitArray(int32_t size) { + m_bits.SetSize((size + 31) >> 5); + m_size = size; +} +CBC_CommonBitArray::~CBC_CommonBitArray() { + m_size = 0; +} +int32_t CBC_CommonBitArray::GetSize() { + return m_size; +} +CFX_Int32Array& CBC_CommonBitArray::GetBits() { + return m_bits; +} +int32_t CBC_CommonBitArray::GetSizeInBytes() { + return (m_size + 7) >> 3; +} +FX_BOOL CBC_CommonBitArray::Get(int32_t i) { + return (m_bits[i >> 5] & (1 << (i & 0x1f))) != 0; +} +void CBC_CommonBitArray::Set(int32_t i) { + m_bits[i >> 5] |= 1 << (i & 0x1F); +} +void CBC_CommonBitArray::Flip(int32_t i) { + m_bits[i >> 5] ^= 1 << (i & 0x1F); +} +void CBC_CommonBitArray::SetBulk(int32_t i, int32_t newBits) { + m_bits[i >> 5] = newBits; +} +void CBC_CommonBitArray::Clear() { + FXSYS_memset(&m_bits[0], 0x00, m_bits.GetSize() * sizeof(int32_t)); +} +FX_BOOL CBC_CommonBitArray::IsRange(int32_t start, + int32_t end, + FX_BOOL value, + int32_t& e) { + if (end < start) { + e = BCExceptionEndLessThanStart; + return FALSE; + } + if (end == start) { + return TRUE; + } + end--; + int32_t firstInt = start >> 5; + int32_t lastInt = end >> 5; + int32_t i; + for (i = firstInt; i <= lastInt; i++) { + int32_t firstBit = i > firstInt ? 0 : start & 0x1F; + int32_t lastBit = i < lastInt ? 31 : end & 0x1F; + int32_t mask; + if (firstBit == 0 && lastBit == 31) { + mask = -1; + } else { + mask = 0; + for (int32_t j = firstBit; j <= lastBit; j++) { + mask |= 1 << j; + } + } + if ((m_bits[i] & mask) != (value ? mask : 0)) { + return FALSE; + } + } + return TRUE; +} +int32_t* CBC_CommonBitArray::GetBitArray() { + return &m_bits[0]; +} +void CBC_CommonBitArray::Reverse() { + int32_t* newBits = FX_Alloc(int32_t, m_bits.GetSize()); + FXSYS_memset(newBits, 0x00, m_bits.GetSize() * sizeof(int32_t)); + int32_t size = m_size; + int32_t i; + for (i = 0; i < size; i++) { + if (Get(size - i - 1)) { + newBits[i >> 5] |= 1 << (i & 0x1F); + } + } + FXSYS_memcpy(&m_bits[0], newBits, m_bits.GetSize() * sizeof(int32_t)); + FX_Free(newBits); +} diff --git a/xfa/fxbarcode/common/BC_CommonBitArray.h b/xfa/fxbarcode/common/BC_CommonBitArray.h new file mode 100644 index 0000000000..6ddd789480 --- /dev/null +++ b/xfa/fxbarcode/common/BC_CommonBitArray.h @@ -0,0 +1,35 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef XFA_FXBARCODE_COMMON_BC_COMMONBITARRAY_H_ +#define XFA_FXBARCODE_COMMON_BC_COMMONBITARRAY_H_ + +#include "core/include/fxcrt/fx_basic.h" + +class CBC_CommonBitArray { + public: + CBC_CommonBitArray(CBC_CommonBitArray* array); + CBC_CommonBitArray(int32_t size); + CBC_CommonBitArray(); + virtual ~CBC_CommonBitArray(); + int32_t GetSize(); + CFX_Int32Array& GetBits(); + int32_t GetSizeInBytes(); + FX_BOOL Get(int32_t i); + void Set(int32_t i); + void Flip(int32_t i); + void SetBulk(int32_t i, int32_t newBits); + FX_BOOL IsRange(int32_t start, int32_t end, FX_BOOL value, int32_t& e); + int32_t* GetBitArray(); + void Reverse(); + void Clear(); + + private: + int32_t m_size; + CFX_Int32Array m_bits; +}; + +#endif // XFA_FXBARCODE_COMMON_BC_COMMONBITARRAY_H_ diff --git a/xfa/fxbarcode/common/BC_CommonBitMatrix.cpp b/xfa/fxbarcode/common/BC_CommonBitMatrix.cpp new file mode 100644 index 0000000000..a8f87e7ec4 --- /dev/null +++ b/xfa/fxbarcode/common/BC_CommonBitMatrix.cpp @@ -0,0 +1,146 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com +// Original code is licensed as follows: +/* + * Copyright 2007 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "xfa/fxbarcode/common/BC_CommonBitArray.h" +#include "xfa/fxbarcode/common/BC_CommonBitMatrix.h" +#include "xfa/fxbarcode/utils.h" + +CBC_CommonBitMatrix::CBC_CommonBitMatrix() { + m_width = 0; + m_height = 0; + m_rowSize = 0; + m_bits = NULL; +} +void CBC_CommonBitMatrix::Init(int32_t dimension) { + m_width = dimension; + m_height = dimension; + int32_t rowSize = (m_height + 31) >> 5; + m_rowSize = rowSize; + m_bits = FX_Alloc2D(int32_t, m_rowSize, m_height); + FXSYS_memset(m_bits, 0, m_rowSize * m_height * sizeof(int32_t)); +} +void CBC_CommonBitMatrix::Init(int32_t width, int32_t height) { + m_width = width; + m_height = height; + int32_t rowSize = (width + 31) >> 5; + m_rowSize = rowSize; + m_bits = FX_Alloc2D(int32_t, m_rowSize, m_height); + FXSYS_memset(m_bits, 0, m_rowSize * m_height * sizeof(int32_t)); +} +CBC_CommonBitMatrix::~CBC_CommonBitMatrix() { + FX_Free(m_bits); +} +FX_BOOL CBC_CommonBitMatrix::Get(int32_t x, int32_t y) { + int32_t offset = y * m_rowSize + (x >> 5); + if (offset >= m_rowSize * m_height || offset < 0) { + return false; + } + return ((((FX_DWORD)m_bits[offset]) >> (x & 0x1f)) & 1) != 0; +} +int32_t* CBC_CommonBitMatrix::GetBits() { + return m_bits; +} +void CBC_CommonBitMatrix::Set(int32_t x, int32_t y) { + int32_t offset = y * m_rowSize + (x >> 5); + if (offset >= m_rowSize * m_height || offset < 0) { + return; + } + m_bits[offset] |= 1 << (x & 0x1f); +} +void CBC_CommonBitMatrix::Flip(int32_t x, int32_t y) { + int32_t offset = y * m_rowSize + (x >> 5); + m_bits[offset] ^= 1 << (x & 0x1f); +} +void CBC_CommonBitMatrix::Clear() { + FXSYS_memset(m_bits, 0, m_rowSize * m_height * sizeof(int32_t)); +} +void CBC_CommonBitMatrix::SetRegion(int32_t left, + int32_t top, + int32_t width, + int32_t height, + int32_t& e) { + if (top < 0 || left < 0) { + e = BCExceptionLeftAndTopMustBeNonnegative; + return; + } + if (height < 1 || width < 1) { + e = BCExceptionHeightAndWidthMustBeAtLeast1; + return; + } + int32_t right = left + width; + int32_t bottom = top + height; + if (m_height < bottom || m_width < right) { + e = BCExceptionRegionMustFitInsideMatrix; + return; + } + int32_t y; + for (y = top; y < bottom; y++) { + int32_t offset = y * m_rowSize; + int32_t x; + for (x = left; x < right; x++) { + m_bits[offset + (x >> 5)] |= 1 << (x & 0x1f); + } + } +} +CBC_CommonBitArray* CBC_CommonBitMatrix::GetRow(int32_t y, + CBC_CommonBitArray* row) { + CBC_CommonBitArray* rowArray = NULL; + if (row == NULL || row->GetSize() < m_width) { + rowArray = new CBC_CommonBitArray(m_width); + } else { + rowArray = new CBC_CommonBitArray(row); + } + int32_t offset = y * m_rowSize; + int32_t x; + for (x = 0; x < m_rowSize; x++) { + rowArray->SetBulk(x << 5, m_bits[offset + x]); + } + return rowArray; +} +void CBC_CommonBitMatrix::SetRow(int32_t y, CBC_CommonBitArray* row) { + int32_t l = y * m_rowSize; + for (int32_t i = 0; i < m_rowSize; i++) { + m_bits[l] = row->GetBitArray()[i]; + l++; + } +} +void CBC_CommonBitMatrix::SetCol(int32_t y, CBC_CommonBitArray* col) { + for (int32_t i = 0; i < col->GetBits().GetSize(); i++) { + m_bits[i * m_rowSize + y] = col->GetBitArray()[i]; + } +} +int32_t CBC_CommonBitMatrix::GetWidth() { + return m_width; +} +int32_t CBC_CommonBitMatrix::GetHeight() { + return m_height; +} +int32_t CBC_CommonBitMatrix::GetRowSize() { + return m_rowSize; +} +int32_t CBC_CommonBitMatrix::GetDimension(int32_t& e) { + if (m_width != m_height) { + e = BCExceptionCanNotCallGetDimensionOnNonSquareMatrix; + return 0; + } + return m_width; +} diff --git a/xfa/fxbarcode/common/BC_CommonBitMatrix.h b/xfa/fxbarcode/common/BC_CommonBitMatrix.h new file mode 100644 index 0000000000..78b42641dd --- /dev/null +++ b/xfa/fxbarcode/common/BC_CommonBitMatrix.h @@ -0,0 +1,46 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef XFA_FXBARCODE_COMMON_BC_COMMONBITMATRIX_H_ +#define XFA_FXBARCODE_COMMON_BC_COMMONBITMATRIX_H_ + +#include "core/include/fxcrt/fx_system.h" + +class CBC_CommonBitArray; + +class CBC_CommonBitMatrix { + public: + CBC_CommonBitMatrix(); + virtual ~CBC_CommonBitMatrix(); + FX_BOOL Get(int32_t x, int32_t y); + void Set(int32_t x, int32_t y); + void Flip(int32_t x, int32_t y); + void Clear(); + void SetRegion(int32_t left, + int32_t top, + int32_t width, + int32_t height, + int32_t& e); + CBC_CommonBitArray* GetRow(int32_t y, CBC_CommonBitArray* row); + void SetRow(int32_t y, CBC_CommonBitArray* row); + CBC_CommonBitArray* GetCol(int32_t y, CBC_CommonBitArray* row); + void SetCol(int32_t y, CBC_CommonBitArray* col); + int32_t GetWidth(); + int32_t GetHeight(); + int32_t GetRowSize(); + int32_t GetDimension(int32_t& e); + virtual void Init(int32_t dimension); + virtual void Init(int32_t width, int32_t height); + int32_t* GetBits(); + + private: + int32_t m_width; + int32_t m_height; + int32_t m_rowSize; + int32_t* m_bits; +}; + +#endif // XFA_FXBARCODE_COMMON_BC_COMMONBITMATRIX_H_ diff --git a/xfa/fxbarcode/common/BC_CommonBitSource.cpp b/xfa/fxbarcode/common/BC_CommonBitSource.cpp new file mode 100644 index 0000000000..af91d5e0bd --- /dev/null +++ b/xfa/fxbarcode/common/BC_CommonBitSource.cpp @@ -0,0 +1,71 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com +// Original code is licensed as follows: +/* + * Copyright 2007 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "xfa/fxbarcode/common/BC_CommonBitSource.h" + +CBC_CommonBitSource::CBC_CommonBitSource(CFX_ByteArray* bytes) { + m_bytes.Copy((*bytes)); + m_bitOffset = 0; + m_byteOffset = 0; +} +CBC_CommonBitSource::~CBC_CommonBitSource() {} +int32_t CBC_CommonBitSource::ReadBits(int32_t numBits, int32_t& e) { + if (numBits < 1 || numBits > 32) { + e = BCExceptionIllegalArgument; + return 0; + } + int32_t result = 0; + if (m_bitOffset > 0) { + int32_t bitsLeft = 8 - m_bitOffset; + int32_t toRead = numBits < bitsLeft ? numBits : bitsLeft; + int32_t bitsToNotRead = bitsLeft - toRead; + int32_t mask = (0xff >> (8 - toRead)) << bitsToNotRead; + result = (m_bytes[m_byteOffset] & mask) >> bitsToNotRead; + numBits -= toRead; + m_bitOffset += toRead; + if (m_bitOffset == 8) { + m_bitOffset = 0; + m_byteOffset++; + } + } + if (numBits > 0) { + while (numBits >= 8) { + result = (result << 8) | (m_bytes[m_byteOffset] & 0xff); + m_byteOffset++; + numBits -= 8; + } + if (numBits > 0) { + int32_t bitsToNotRead = 8 - numBits; + int32_t mask = (0xff >> bitsToNotRead) << bitsToNotRead; + result = (result << numBits) | + ((m_bytes[m_byteOffset] & mask) >> bitsToNotRead); + m_bitOffset += numBits; + } + } + return result; +} +int32_t CBC_CommonBitSource::Available() { + return 8 * (m_bytes.GetSize() - m_byteOffset) - m_bitOffset; +} +int32_t CBC_CommonBitSource::getByteOffset() { + return m_byteOffset; +} diff --git a/xfa/fxbarcode/common/BC_CommonBitSource.h b/xfa/fxbarcode/common/BC_CommonBitSource.h new file mode 100644 index 0000000000..7617a6f19d --- /dev/null +++ b/xfa/fxbarcode/common/BC_CommonBitSource.h @@ -0,0 +1,27 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef XFA_FXBARCODE_COMMON_BC_COMMONBITSOURCE_H_ +#define XFA_FXBARCODE_COMMON_BC_COMMONBITSOURCE_H_ + +#include "core/include/fxcrt/fx_basic.h" +#include "xfa/fxbarcode/utils.h" + +class CBC_CommonBitSource { + public: + CBC_CommonBitSource(CFX_ByteArray* bytes); + virtual ~CBC_CommonBitSource(); + int32_t ReadBits(int32_t numBits, int32_t& e); + int32_t Available(); + int32_t getByteOffset(); + + private: + CFX_ByteArray m_bytes; + int32_t m_byteOffset; + int32_t m_bitOffset; +}; + +#endif // XFA_FXBARCODE_COMMON_BC_COMMONBITSOURCE_H_ diff --git a/xfa/fxbarcode/common/BC_CommonByteArray.cpp b/xfa/fxbarcode/common/BC_CommonByteArray.cpp new file mode 100644 index 0000000000..1fd6e46420 --- /dev/null +++ b/xfa/fxbarcode/common/BC_CommonByteArray.cpp @@ -0,0 +1,99 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com +// Original code is licensed as follows: +/* + * Copyright 2008 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <algorithm> + +#include "xfa/fxbarcode/common/BC_CommonByteArray.h" + +CBC_CommonByteArray::CBC_CommonByteArray() { + m_bytes = NULL; + m_size = 0; + m_index = 0; +} +CBC_CommonByteArray::CBC_CommonByteArray(int32_t size) { + m_size = size; + m_bytes = FX_Alloc(uint8_t, size); + FXSYS_memset(m_bytes, 0, size); + m_index = 0; +} +CBC_CommonByteArray::CBC_CommonByteArray(uint8_t* byteArray, int32_t size) { + m_size = size; + m_bytes = FX_Alloc(uint8_t, size); + FXSYS_memcpy(m_bytes, byteArray, size); + m_index = size; +} +CBC_CommonByteArray::~CBC_CommonByteArray() { + FX_Free(m_bytes); +} +int32_t CBC_CommonByteArray::At(int32_t index) { + return m_bytes[index] & 0xff; +} +void CBC_CommonByteArray::Set(int32_t index, int32_t value) { + m_bytes[index] = (uint8_t)value; +} +int32_t CBC_CommonByteArray::Size() { + return m_size; +} +FX_BOOL CBC_CommonByteArray::IsEmpty() { + return m_size == 0; +} +void CBC_CommonByteArray::AppendByte(int32_t value) { + if (m_size == 0 || m_index >= m_size) { + int32_t newSize = std::max(32, m_size << 1); + Reserve(newSize); + } + m_bytes[m_index] = (uint8_t)value; + m_index++; +} +void CBC_CommonByteArray::Reserve(int32_t capacity) { + if (m_bytes == NULL || m_size < capacity) { + uint8_t* newArray = FX_Alloc(uint8_t, capacity); + if (m_bytes) { + FXSYS_memcpy(newArray, m_bytes, m_size); + FXSYS_memset(newArray + m_size, 0, capacity - m_size); + } else { + FXSYS_memset(newArray, 0, capacity); + } + FX_Free(m_bytes); + m_bytes = newArray; + m_size = capacity; + } +} +void CBC_CommonByteArray::Set(uint8_t* source, int32_t offset, int32_t count) { + FX_Free(m_bytes); + m_bytes = FX_Alloc(uint8_t, count); + m_size = count; + FXSYS_memcpy(m_bytes, source + offset, count); + m_index = count; +} +void CBC_CommonByteArray::Set(CFX_ByteArray* source, + int32_t offset, + int32_t count) { + FX_Free(m_bytes); + m_bytes = FX_Alloc(uint8_t, count); + m_size = count; + int32_t i; + for (i = 0; i < count; i++) { + m_bytes[i] = source->operator[](i + offset); + } + m_index = m_size; +} diff --git a/xfa/fxbarcode/common/BC_CommonByteArray.h b/xfa/fxbarcode/common/BC_CommonByteArray.h new file mode 100644 index 0000000000..69d470b0e5 --- /dev/null +++ b/xfa/fxbarcode/common/BC_CommonByteArray.h @@ -0,0 +1,33 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef XFA_FXBARCODE_COMMON_BC_COMMONBYTEARRAY_H_ +#define XFA_FXBARCODE_COMMON_BC_COMMONBYTEARRAY_H_ + +#include "core/include/fxcrt/fx_basic.h" + +class CBC_CommonByteArray { + private: + int32_t m_size; + int32_t m_index; + uint8_t* m_bytes; + + public: + CBC_CommonByteArray(); + CBC_CommonByteArray(int32_t size); + CBC_CommonByteArray(uint8_t* byteArray, int32_t size); + virtual ~CBC_CommonByteArray(); + int32_t At(int32_t index); + void Set(int32_t index, int32_t value); + int32_t Size(); + FX_BOOL IsEmpty(); + void AppendByte(int32_t value); + void Reserve(int32_t capacity); + void Set(uint8_t* source, int32_t offset, int32_t count); + void Set(CFX_ByteArray* source, int32_t offset, int32_t count); +}; + +#endif // XFA_FXBARCODE_COMMON_BC_COMMONBYTEARRAY_H_ diff --git a/xfa/fxbarcode/common/BC_CommonByteMatrix.cpp b/xfa/fxbarcode/common/BC_CommonByteMatrix.cpp new file mode 100644 index 0000000000..c9ed7495c0 --- /dev/null +++ b/xfa/fxbarcode/common/BC_CommonByteMatrix.cpp @@ -0,0 +1,64 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com +// Original code is licensed as follows: +/* + * Copyright 2008 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "core/include/fxcrt/fx_memory.h" +#include "xfa/fxbarcode/common/BC_CommonByteMatrix.h" + +CBC_CommonByteMatrix::CBC_CommonByteMatrix(int32_t width, int32_t height) { + m_height = height; + m_width = width; + m_bytes = NULL; +} +void CBC_CommonByteMatrix::Init() { + m_bytes = FX_Alloc2D(uint8_t, m_height, m_width); + FXSYS_memset(m_bytes, 0xff, m_height * m_width); +} +CBC_CommonByteMatrix::~CBC_CommonByteMatrix() { + FX_Free(m_bytes); +} +int32_t CBC_CommonByteMatrix::GetHeight() { + return m_height; +} +int32_t CBC_CommonByteMatrix::GetWidth() { + return m_width; +} +uint8_t CBC_CommonByteMatrix::Get(int32_t x, int32_t y) { + return m_bytes[y * m_width + x]; +} +void CBC_CommonByteMatrix::Set(int32_t x, int32_t y, int32_t value) { + m_bytes[y * m_width + x] = (uint8_t)value; +} +void CBC_CommonByteMatrix::Set(int32_t x, int32_t y, uint8_t value) { + m_bytes[y * m_width + x] = value; +} +void CBC_CommonByteMatrix::clear(uint8_t value) { + int32_t y; + for (y = 0; y < m_height; y++) { + int32_t x; + for (x = 0; x < m_width; x++) { + m_bytes[y * m_width + x] = value; + } + } +} +uint8_t* CBC_CommonByteMatrix::GetArray() { + return m_bytes; +} diff --git a/xfa/fxbarcode/common/BC_CommonByteMatrix.h b/xfa/fxbarcode/common/BC_CommonByteMatrix.h new file mode 100644 index 0000000000..271feef34f --- /dev/null +++ b/xfa/fxbarcode/common/BC_CommonByteMatrix.h @@ -0,0 +1,34 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef XFA_FXBARCODE_COMMON_BC_COMMONBYTEMATRIX_H_ +#define XFA_FXBARCODE_COMMON_BC_COMMONBYTEMATRIX_H_ + +#include <stdint.h> + +#include "core/include/fxcrt/fx_system.h" + +class CBC_CommonByteMatrix { + public: + CBC_CommonByteMatrix(int32_t width, int32_t height); + virtual ~CBC_CommonByteMatrix(); + int32_t GetHeight(); + int32_t GetWidth(); + uint8_t Get(int32_t x, int32_t y); + uint8_t* GetArray(); + + void Set(int32_t x, int32_t y, int32_t value); + void Set(int32_t x, int32_t y, uint8_t value); + void clear(uint8_t value); + virtual void Init(); + + private: + uint8_t* m_bytes; + int32_t m_width; + int32_t m_height; +}; + +#endif // XFA_FXBARCODE_COMMON_BC_COMMONBYTEMATRIX_H_ diff --git a/xfa/fxbarcode/common/BC_CommonCharacterSetECI.cpp b/xfa/fxbarcode/common/BC_CommonCharacterSetECI.cpp new file mode 100644 index 0000000000..d6fa9e472e --- /dev/null +++ b/xfa/fxbarcode/common/BC_CommonCharacterSetECI.cpp @@ -0,0 +1,44 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com +// Original code is licensed as follows: +/* + * Copyright 2008 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "xfa/fxbarcode/common/BC_CommonCharacterSetECI.h" +#include "xfa/fxbarcode/common/BC_CommonECI.h" + +void CBC_CommonCharacterSetECI::initialize() {} +CBC_CommonCharacterSetECI::CBC_CommonCharacterSetECI( + int32_t value, + CFX_ByteString encodingName) + : CBC_CommonECI(value), m_encodingName(encodingName) {} +CBC_CommonCharacterSetECI::~CBC_CommonCharacterSetECI() {} +CFX_ByteString CBC_CommonCharacterSetECI::GetEncodingName() { + return m_encodingName; +} +void CBC_CommonCharacterSetECI::AddCharacterSet(int32_t value, + CFX_ByteString encodingName) {} +CBC_CommonCharacterSetECI* CBC_CommonCharacterSetECI::GetCharacterSetECIByValue( + int32_t value) { + return NULL; +} +CBC_CommonCharacterSetECI* CBC_CommonCharacterSetECI::GetCharacterSetECIByName( + const CFX_ByteString& name) { + return NULL; +} diff --git a/xfa/fxbarcode/common/BC_CommonCharacterSetECI.h b/xfa/fxbarcode/common/BC_CommonCharacterSetECI.h new file mode 100644 index 0000000000..18a676a449 --- /dev/null +++ b/xfa/fxbarcode/common/BC_CommonCharacterSetECI.h @@ -0,0 +1,29 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef XFA_FXBARCODE_COMMON_BC_COMMONCHARACTERSETECI_H_ +#define XFA_FXBARCODE_COMMON_BC_COMMONCHARACTERSETECI_H_ + +#include "core/include/fxcrt/fx_string.h" +#include "xfa/fxbarcode/common/BC_CommonECI.h" + +class CBC_CommonCharacterSetECI : public CBC_CommonECI { + public: + CBC_CommonCharacterSetECI(int32_t value, CFX_ByteString encodingName); + virtual ~CBC_CommonCharacterSetECI(); + CFX_ByteString GetEncodingName(); + static void AddCharacterSet(int32_t value, CFX_ByteString encodingName); + int32_t GetValue(); + static CBC_CommonCharacterSetECI* GetCharacterSetECIByValue(int32_t value); + static CBC_CommonCharacterSetECI* GetCharacterSetECIByName( + const CFX_ByteString& name); + + private: + CFX_ByteString m_encodingName; + static void initialize(); +}; + +#endif // XFA_FXBARCODE_COMMON_BC_COMMONCHARACTERSETECI_H_ diff --git a/xfa/fxbarcode/common/BC_CommonDecoderResult.cpp b/xfa/fxbarcode/common/BC_CommonDecoderResult.cpp new file mode 100644 index 0000000000..0c545c4eba --- /dev/null +++ b/xfa/fxbarcode/common/BC_CommonDecoderResult.cpp @@ -0,0 +1,77 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com +// Original code is licensed as follows: +/* + * Copyright 2007 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "core/include/fxcrt/fx_basic.h" +#include "xfa/fxbarcode/common/BC_CommonDecoderResult.h" +#include "xfa/fxbarcode/pdf417/BC_PDF417ResultMetadata.h" +#include "xfa/fxbarcode/qrcode/BC_QRCoderErrorCorrectionLevel.h" +#include "xfa/fxbarcode/utils.h" + +CBC_CommonDecoderResult::CBC_CommonDecoderResult() {} +void CBC_CommonDecoderResult::Init(const CFX_ByteArray& rawBytes, + const CFX_ByteString& text, + const CFX_Int32Array& byteSegments, + CBC_QRCoderErrorCorrectionLevel* ecLevel, + int32_t& e) { + if (text.IsEmpty()) { + e = BCExceptionIllegalArgument; + return; + } + m_rawBytes.Copy(rawBytes); + m_text = text; + m_byteSegments.Copy(byteSegments); + m_ecLevel = ecLevel; + m_other = NULL; +} +void CBC_CommonDecoderResult::Init(const CFX_ByteArray& rawBytes, + const CFX_ByteString& text, + const CFX_PtrArray& byteSegments, + const CFX_ByteString& ecLevel, + int32_t& e) { + if (text.IsEmpty()) { + e = BCExceptionIllegalArgument; + return; + } + m_rawBytes.Copy(rawBytes); + m_text = text; + m_pdf417byteSegments.Copy(byteSegments); + m_pdf417ecLevel = ecLevel; + m_other = NULL; +} +void CBC_CommonDecoderResult::setOther(CBC_PDF417ResultMetadata* other) { + m_other = other; +} +CBC_CommonDecoderResult::~CBC_CommonDecoderResult() { + delete m_other; +} +const CFX_ByteArray& CBC_CommonDecoderResult::GetRawBytes() { + return m_rawBytes; +} +const CFX_Int32Array& CBC_CommonDecoderResult::GetByteSegments() { + return m_byteSegments; +} +const CFX_ByteString& CBC_CommonDecoderResult::GetText() { + return m_text; +} +CBC_QRCoderErrorCorrectionLevel* CBC_CommonDecoderResult::GetECLevel() { + return m_ecLevel; +} diff --git a/xfa/fxbarcode/common/BC_CommonDecoderResult.h b/xfa/fxbarcode/common/BC_CommonDecoderResult.h new file mode 100644 index 0000000000..dbdb9d34d4 --- /dev/null +++ b/xfa/fxbarcode/common/BC_CommonDecoderResult.h @@ -0,0 +1,45 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef XFA_FXBARCODE_COMMON_BC_COMMONDECODERRESULT_H_ +#define XFA_FXBARCODE_COMMON_BC_COMMONDECODERRESULT_H_ + +#include "core/include/fxcrt/fx_basic.h" + +class CBC_QRCoderErrorCorrectionLevel; +class CBC_PDF417ResultMetadata; + +class CBC_CommonDecoderResult { + public: + CBC_CommonDecoderResult(); + virtual ~CBC_CommonDecoderResult(); + const CFX_ByteArray& GetRawBytes(); + const CFX_ByteString& GetText(); + const CFX_Int32Array& GetByteSegments(); + CBC_QRCoderErrorCorrectionLevel* GetECLevel(); + virtual void Init(const CFX_ByteArray& rawBytes, + const CFX_ByteString& text, + const CFX_Int32Array& byteSegments, + CBC_QRCoderErrorCorrectionLevel* ecLevel, + int32_t& e); + virtual void Init(const CFX_ByteArray& rawBytes, + const CFX_ByteString& text, + const CFX_PtrArray& byteSegments, + const CFX_ByteString& ecLevel, + int32_t& e); + void setOther(CBC_PDF417ResultMetadata* other); + + private: + CFX_ByteArray m_rawBytes; + CFX_ByteString m_text; + CFX_Int32Array m_byteSegments; + CFX_PtrArray m_pdf417byteSegments; + CBC_QRCoderErrorCorrectionLevel* m_ecLevel; + CFX_ByteString m_pdf417ecLevel; + CBC_PDF417ResultMetadata* m_other; +}; + +#endif // XFA_FXBARCODE_COMMON_BC_COMMONDECODERRESULT_H_ diff --git a/xfa/fxbarcode/common/BC_CommonECI.cpp b/xfa/fxbarcode/common/BC_CommonECI.cpp new file mode 100644 index 0000000000..4e37aec566 --- /dev/null +++ b/xfa/fxbarcode/common/BC_CommonECI.cpp @@ -0,0 +1,42 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com +// Original code is licensed as follows: +/* + * Copyright 2008 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "xfa/fxbarcode/common/BC_CommonCharacterSetECI.h" +#include "xfa/fxbarcode/common/BC_CommonECI.h" +#include "xfa/fxbarcode/utils.h" + +CBC_CommonECI::CBC_CommonECI(int32_t value) { + m_value = value; +} +CBC_CommonECI::~CBC_CommonECI() {} +int32_t CBC_CommonECI::GetValue() { + return m_value; +} +CBC_CommonECI* CBC_CommonECI::GetEICByValue(int32_t value, int32_t& e) { + if (value < 0 || value > 999999) { + e = BCExceptionBadECI; + return NULL; + } + if (value < 900) { + } + return NULL; +} diff --git a/xfa/fxbarcode/common/BC_CommonECI.h b/xfa/fxbarcode/common/BC_CommonECI.h new file mode 100644 index 0000000000..20b3e76bb3 --- /dev/null +++ b/xfa/fxbarcode/common/BC_CommonECI.h @@ -0,0 +1,24 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef XFA_FXBARCODE_COMMON_BC_COMMONECI_H_ +#define XFA_FXBARCODE_COMMON_BC_COMMONECI_H_ + +#include <stdint.h> + +class CBC_CommonECI { + public: + CBC_CommonECI(int32_t value); + virtual ~CBC_CommonECI(); + + int32_t GetValue(); + static CBC_CommonECI* GetEICByValue(int32_t value, int32_t& e); + + private: + int32_t m_value; +}; + +#endif // XFA_FXBARCODE_COMMON_BC_COMMONECI_H_ diff --git a/xfa/fxbarcode/common/BC_CommonPerspectiveTransform.cpp b/xfa/fxbarcode/common/BC_CommonPerspectiveTransform.cpp new file mode 100644 index 0000000000..daa6189e56 --- /dev/null +++ b/xfa/fxbarcode/common/BC_CommonPerspectiveTransform.cpp @@ -0,0 +1,152 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com +// Original code is licensed as follows: +/* + * Copyright 2007 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "xfa/fxbarcode/common/BC_CommonPerspectiveTransform.h" + +#include <memory> + +#include "core/include/fxcrt/fx_basic.h" +#include "xfa/fxbarcode/utils.h" + +CBC_CommonPerspectiveTransform::CBC_CommonPerspectiveTransform(FX_FLOAT a11, + FX_FLOAT a21, + FX_FLOAT a31, + FX_FLOAT a12, + FX_FLOAT a22, + FX_FLOAT a32, + FX_FLOAT a13, + FX_FLOAT a23, + FX_FLOAT a33) + : m_a11(a11), + m_a12(a12), + m_a13(a13), + m_a21(a21), + m_a22(a22), + m_a23(a23), + m_a31(a31), + m_a32(a32), + m_a33(a33) {} +CBC_CommonPerspectiveTransform::~CBC_CommonPerspectiveTransform() {} +CBC_CommonPerspectiveTransform* +CBC_CommonPerspectiveTransform::QuadrilateralToQuadrilateral(FX_FLOAT x0, + FX_FLOAT y0, + FX_FLOAT x1, + FX_FLOAT y1, + FX_FLOAT x2, + FX_FLOAT y2, + FX_FLOAT x3, + FX_FLOAT y3, + FX_FLOAT x0p, + FX_FLOAT y0p, + FX_FLOAT x1p, + FX_FLOAT y1p, + FX_FLOAT x2p, + FX_FLOAT y2p, + FX_FLOAT x3p, + FX_FLOAT y3p) { + std::unique_ptr<CBC_CommonPerspectiveTransform> qToS( + QuadrilateralToSquare(x0, y0, x1, y1, x2, y2, x3, y3)); + std::unique_ptr<CBC_CommonPerspectiveTransform> sToQ( + SquareToQuadrilateral(x0p, y0p, x1p, y1p, x2p, y2p, x3p, y3p)); + return sToQ->Times(*(qToS.get())); +} +void CBC_CommonPerspectiveTransform::TransformPoints(CFX_FloatArray* points) { + int32_t max = points->GetSize(); + FX_FLOAT a11 = m_a11; + FX_FLOAT a12 = m_a12; + FX_FLOAT a13 = m_a13; + FX_FLOAT a21 = m_a21; + FX_FLOAT a22 = m_a22; + FX_FLOAT a23 = m_a23; + FX_FLOAT a31 = m_a31; + FX_FLOAT a32 = m_a32; + FX_FLOAT a33 = m_a33; + int32_t i; + for (i = 0; i < max; i += 2) { + FX_FLOAT x = (*points)[i]; + FX_FLOAT y = (*points)[i + 1]; + FX_FLOAT denominator = a13 * x + a23 * y + a33; + (*points)[i] = (a11 * x + a21 * y + a31) / denominator; + (*points)[i + 1] = (a12 * x + a22 * y + a32) / denominator; + } +} +CBC_CommonPerspectiveTransform* +CBC_CommonPerspectiveTransform::SquareToQuadrilateral(FX_FLOAT x0, + FX_FLOAT y0, + FX_FLOAT x1, + FX_FLOAT y1, + FX_FLOAT x2, + FX_FLOAT y2, + FX_FLOAT x3, + FX_FLOAT y3) { + FX_FLOAT dy2 = y3 - y2; + FX_FLOAT dy3 = y0 - y1 + y2 - y3; + if ((dy2 == 0.0f) && (dy3 == 0.0f)) { + return new CBC_CommonPerspectiveTransform(x1 - x0, x2 - x1, x0, y1 - y0, + y2 - y1, y0, 0.0f, 0.0f, 1.0f); + } else { + FX_FLOAT dx1 = x1 - x2; + FX_FLOAT dx2 = x3 - x2; + FX_FLOAT dx3 = x0 - x1 + x2 - x3; + FX_FLOAT dy1 = y1 - y2; + FX_FLOAT denominator = dx1 * dy2 - dx2 * dy1; + FX_FLOAT a13 = (dx3 * dy2 - dx2 * dy3) / denominator; + FX_FLOAT a23 = (dx1 * dy3 - dx3 * dy1) / denominator; + return new CBC_CommonPerspectiveTransform( + x1 - x0 + a13 * x1, x3 - x0 + a23 * x3, x0, y1 - y0 + a13 * y1, + y3 - y0 + a23 * y3, y0, a13, a23, 1.0f); + } +} +CBC_CommonPerspectiveTransform* +CBC_CommonPerspectiveTransform::QuadrilateralToSquare(FX_FLOAT x0, + FX_FLOAT y0, + FX_FLOAT x1, + FX_FLOAT y1, + FX_FLOAT x2, + FX_FLOAT y2, + FX_FLOAT x3, + FX_FLOAT y3) { + std::unique_ptr<CBC_CommonPerspectiveTransform> temp1( + SquareToQuadrilateral(x0, y0, x1, y1, x2, y2, x3, y3)); + return temp1->BuildAdjoint(); +} +CBC_CommonPerspectiveTransform* CBC_CommonPerspectiveTransform::BuildAdjoint() { + return new CBC_CommonPerspectiveTransform( + m_a22 * m_a33 - m_a23 * m_a32, m_a23 * m_a31 - m_a21 * m_a33, + m_a21 * m_a32 - m_a22 * m_a31, m_a13 * m_a32 - m_a12 * m_a33, + m_a11 * m_a33 - m_a13 * m_a31, m_a12 * m_a31 - m_a11 * m_a32, + m_a12 * m_a23 - m_a13 * m_a22, m_a13 * m_a21 - m_a11 * m_a23, + m_a11 * m_a22 - m_a12 * m_a21); +} +CBC_CommonPerspectiveTransform* CBC_CommonPerspectiveTransform::Times( + CBC_CommonPerspectiveTransform& other) { + return new CBC_CommonPerspectiveTransform( + m_a11 * other.m_a11 + m_a21 * other.m_a12 + m_a31 * other.m_a13, + m_a11 * other.m_a21 + m_a21 * other.m_a22 + m_a31 * other.m_a23, + m_a11 * other.m_a31 + m_a21 * other.m_a32 + m_a31 * other.m_a33, + m_a12 * other.m_a11 + m_a22 * other.m_a12 + m_a32 * other.m_a13, + m_a12 * other.m_a21 + m_a22 * other.m_a22 + m_a32 * other.m_a23, + m_a12 * other.m_a31 + m_a22 * other.m_a32 + m_a32 * other.m_a33, + m_a13 * other.m_a11 + m_a23 * other.m_a12 + m_a33 * other.m_a13, + m_a13 * other.m_a21 + m_a23 * other.m_a22 + m_a33 * other.m_a23, + m_a13 * other.m_a31 + m_a23 * other.m_a32 + m_a33 * other.m_a33); +} diff --git a/xfa/fxbarcode/common/BC_CommonPerspectiveTransform.h b/xfa/fxbarcode/common/BC_CommonPerspectiveTransform.h new file mode 100644 index 0000000000..36defd8146 --- /dev/null +++ b/xfa/fxbarcode/common/BC_CommonPerspectiveTransform.h @@ -0,0 +1,65 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef XFA_FXBARCODE_COMMON_BC_COMMONPERSPECTIVETRANSFORM_H_ +#define XFA_FXBARCODE_COMMON_BC_COMMONPERSPECTIVETRANSFORM_H_ + +#include "core/include/fxcrt/fx_basic.h" + +class CBC_CommonPerspectiveTransform { + public: + CBC_CommonPerspectiveTransform(FX_FLOAT a11, + FX_FLOAT a21, + FX_FLOAT a31, + FX_FLOAT a12, + FX_FLOAT a22, + FX_FLOAT a32, + FX_FLOAT a13, + FX_FLOAT a23, + FX_FLOAT a33); + virtual ~CBC_CommonPerspectiveTransform(); + static CBC_CommonPerspectiveTransform* QuadrilateralToQuadrilateral( + FX_FLOAT x0, + FX_FLOAT y0, + FX_FLOAT x1, + FX_FLOAT y1, + FX_FLOAT x2, + FX_FLOAT y2, + FX_FLOAT x3, + FX_FLOAT y3, + FX_FLOAT x0p, + FX_FLOAT y0p, + FX_FLOAT x1p, + FX_FLOAT y1p, + FX_FLOAT x2p, + FX_FLOAT y2p, + FX_FLOAT x3p, + FX_FLOAT y3p); + static CBC_CommonPerspectiveTransform* SquareToQuadrilateral(FX_FLOAT x0, + FX_FLOAT y0, + FX_FLOAT x1, + FX_FLOAT y1, + FX_FLOAT x2, + FX_FLOAT y2, + FX_FLOAT x3, + FX_FLOAT y3); + static CBC_CommonPerspectiveTransform* QuadrilateralToSquare(FX_FLOAT x0, + FX_FLOAT y0, + FX_FLOAT x1, + FX_FLOAT y1, + FX_FLOAT x2, + FX_FLOAT y2, + FX_FLOAT x3, + FX_FLOAT y3); + CBC_CommonPerspectiveTransform* BuildAdjoint(); + CBC_CommonPerspectiveTransform* Times(CBC_CommonPerspectiveTransform& other); + void TransformPoints(CFX_FloatArray* points); + + private: + FX_FLOAT m_a11, m_a12, m_a13, m_a21, m_a22, m_a23, m_a31, m_a32, m_a33; +}; + +#endif // XFA_FXBARCODE_COMMON_BC_COMMONPERSPECTIVETRANSFORM_H_ diff --git a/xfa/fxbarcode/common/BC_GlobalHistogramBinarizer.cpp b/xfa/fxbarcode/common/BC_GlobalHistogramBinarizer.cpp new file mode 100644 index 0000000000..d4a33229cf --- /dev/null +++ b/xfa/fxbarcode/common/BC_GlobalHistogramBinarizer.cpp @@ -0,0 +1,173 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com +// Original code is licensed as follows: +/* + * Copyright 2009 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "xfa/fxbarcode/common/BC_GlobalHistogramBinarizer.h" + +#include <memory> + +#include "xfa/fxbarcode/BC_Binarizer.h" +#include "xfa/fxbarcode/BC_LuminanceSource.h" +#include "xfa/fxbarcode/common/BC_CommonBitArray.h" +#include "xfa/fxbarcode/common/BC_CommonBitMatrix.h" +#include "xfa/fxbarcode/utils.h" + +const int32_t LUMINANCE_BITS = 5; +const int32_t LUMINANCE_SHIFT = 8 - LUMINANCE_BITS; +const int32_t LUMINANCE_BUCKETS = 1 << LUMINANCE_BITS; + +CBC_GlobalHistogramBinarizer::CBC_GlobalHistogramBinarizer( + CBC_LuminanceSource* source) + : CBC_Binarizer(source) {} +CBC_GlobalHistogramBinarizer::~CBC_GlobalHistogramBinarizer() {} +CBC_CommonBitArray* CBC_GlobalHistogramBinarizer::GetBlackRow( + int32_t y, + CBC_CommonBitArray* row, + int32_t& e) { + CBC_LuminanceSource* source = GetLuminanceSource(); + int32_t width = source->GetWidth(); + std::unique_ptr<CBC_CommonBitArray> result(new CBC_CommonBitArray(width)); + InitArrays(width); + CFX_ByteArray* localLuminances = source->GetRow(y, m_luminance, e); + if (e != BCExceptionNO) { + return result.release(); + } + CFX_Int32Array localBuckets; + localBuckets.Copy(m_buckets); + int32_t x; + for (x = 0; x < width; x++) { + int32_t pixel = (*localLuminances)[x] & 0xff; + localBuckets[pixel >> LUMINANCE_SHIFT]++; + } + int32_t blackPoint = EstimateBlackPoint(localBuckets, e); + if (e != BCExceptionNO) { + return result.release(); + } + int32_t left = (*localLuminances)[0] & 0xff; + int32_t center = (*localLuminances)[1] & 0xff; + for (x = 1; x < width - 1; x++) { + int32_t right = (*localLuminances)[x + 1] & 0xff; + int32_t luminance = ((center << 2) - left - right) >> 1; + if (luminance < blackPoint) { + result->Set(x); + } + left = center; + center = right; + } + return result.release(); +} +CBC_CommonBitMatrix* CBC_GlobalHistogramBinarizer::GetBlackMatrix(int32_t& e) { + CBC_LuminanceSource* source = GetLuminanceSource(); + int32_t width = source->GetWidth(); + int32_t height = source->GetHeight(); + std::unique_ptr<CBC_CommonBitMatrix> matrix(new CBC_CommonBitMatrix()); + matrix->Init(width, height); + InitArrays(width); + CFX_Int32Array localBuckets; + localBuckets.Copy(m_buckets); + int32_t y; + for (y = 1; y < 5; y++) { + int32_t row = height * y / 5; + CFX_ByteArray* localLuminances = source->GetRow(row, m_luminance, e); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + int32_t right = (width << 2) / 5; + int32_t x; + for (x = width / 5; x < right; x++) { + int32_t pixel = (*localLuminances)[x] & 0xff; + localBuckets[pixel >> LUMINANCE_SHIFT]++; + } + } + int32_t blackPoint = EstimateBlackPoint(localBuckets, e); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + std::unique_ptr<CFX_ByteArray> localLuminances(source->GetMatrix()); + for (y = 0; y < height; y++) { + int32_t offset = y * width; + for (int32_t x = 0; x < width; x++) { + int32_t pixel = (*localLuminances)[offset + x] & 0xff; + if (pixel < blackPoint) { + matrix->Set(x, y); + } + } + } + return matrix.release(); +} +void CBC_GlobalHistogramBinarizer::InitArrays(int32_t luminanceSize) { + if (m_luminance.GetSize() < luminanceSize) { + m_luminance.SetSize(luminanceSize); + } + if (m_buckets.GetSize() <= 0) { + m_buckets.SetSize(LUMINANCE_BUCKETS); + } else { + int32_t x; + for (x = 0; x < LUMINANCE_BUCKETS; x++) { + m_buckets[x] = 0; + } + } +} +int32_t CBC_GlobalHistogramBinarizer::EstimateBlackPoint( + CFX_Int32Array& buckets, + int32_t& e) { + int32_t numBuckets = buckets.GetSize(); + int32_t maxBucketCount = 0; + int32_t firstPeak = 0; + int32_t firstPeakSize = 0; + int32_t x; + for (x = 0; x < numBuckets; x++) { + if (buckets[x] > firstPeakSize) { + firstPeak = x; + firstPeakSize = buckets[x]; + } + if (buckets[x] > maxBucketCount) { + maxBucketCount = buckets[x]; + } + } + int32_t secondPeak = 0; + int32_t secondPeakScore = 0; + for (x = 0; x < numBuckets; x++) { + int32_t distanceToBiggest = x - firstPeak; + int32_t score = buckets[x] * distanceToBiggest * distanceToBiggest; + if (score > secondPeakScore) { + secondPeak = x; + secondPeakScore = score; + } + } + if (firstPeak > secondPeak) { + int32_t temp = firstPeak; + firstPeak = secondPeak; + secondPeak = temp; + } + if (secondPeak - firstPeak <= numBuckets >> 4) { + e = BCExceptionRead; + return 0; + } + int32_t bestValley = secondPeak - 1; + int32_t bestValleyScore = -1; + for (x = secondPeak - 1; x > firstPeak; x--) { + int32_t fromFirst = x - firstPeak; + int32_t score = fromFirst * fromFirst * (secondPeak - x) * + (maxBucketCount - buckets[x]); + if (score > bestValleyScore) { + bestValley = x; + bestValleyScore = score; + } + } + return bestValley << LUMINANCE_SHIFT; +} diff --git a/xfa/fxbarcode/common/BC_GlobalHistogramBinarizer.h b/xfa/fxbarcode/common/BC_GlobalHistogramBinarizer.h new file mode 100644 index 0000000000..da13cac402 --- /dev/null +++ b/xfa/fxbarcode/common/BC_GlobalHistogramBinarizer.h @@ -0,0 +1,34 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef XFA_FXBARCODE_COMMON_BC_GLOBALHISTOGRAMBINARIZER_H_ +#define XFA_FXBARCODE_COMMON_BC_GLOBALHISTOGRAMBINARIZER_H_ + +#include "core/include/fxcrt/fx_basic.h" +#include "xfa/fxbarcode/BC_Binarizer.h" + +class CBC_CommonBitArray; +class CBC_CommonBitMatrix; +class CBC_LuminanceSource; + +class CBC_GlobalHistogramBinarizer : public CBC_Binarizer { + public: + CBC_GlobalHistogramBinarizer(CBC_LuminanceSource* source); + virtual ~CBC_GlobalHistogramBinarizer(); + + void InitArrays(int32_t luminanceSize); + CBC_CommonBitMatrix* GetBlackMatrix(int32_t& e); + CBC_CommonBitArray* GetBlackRow(int32_t y, + CBC_CommonBitArray* row, + int32_t& e); + static int32_t EstimateBlackPoint(CFX_Int32Array& buckets, int32_t& e); + + private: + CFX_ByteArray m_luminance; + CFX_Int32Array m_buckets; +}; + +#endif // XFA_FXBARCODE_COMMON_BC_GLOBALHISTOGRAMBINARIZER_H_ diff --git a/xfa/fxbarcode/common/BC_WhiteRectangleDetector.cpp b/xfa/fxbarcode/common/BC_WhiteRectangleDetector.cpp new file mode 100644 index 0000000000..2aeacd1399 --- /dev/null +++ b/xfa/fxbarcode/common/BC_WhiteRectangleDetector.cpp @@ -0,0 +1,254 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com +// Original code is licensed as follows: +/* + * Copyright 2010 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "xfa/fxbarcode/common/BC_WhiteRectangleDetector.h" + +#include <memory> + +#include "xfa/fxbarcode/BC_ResultPoint.h" +#include "xfa/fxbarcode/common/BC_CommonBitMatrix.h" +#include "xfa/fxbarcode/utils.h" + +CBC_WhiteRectangleDetector::CBC_WhiteRectangleDetector( + CBC_CommonBitMatrix* image) { + m_image = image; + m_height = image->GetHeight(); + m_width = image->GetWidth(); + m_leftInit = (m_width - INIT_SIZE) >> 1; + m_rightInit = (m_width + INIT_SIZE) >> 1; + m_upInit = (m_height - INIT_SIZE) >> 1; + m_downInit = (m_height + INIT_SIZE) >> 1; +} +void CBC_WhiteRectangleDetector::Init(int32_t& e) { + if (m_upInit < 0 || m_leftInit < 0 || m_downInit >= m_height || + m_rightInit >= m_width) { + e = BCExceptionNotFound; + BC_EXCEPTION_CHECK_ReturnVoid(e); + } +} +CBC_WhiteRectangleDetector::CBC_WhiteRectangleDetector( + CBC_CommonBitMatrix* image, + int32_t initSize, + int32_t x, + int32_t y) { + m_image = image; + m_height = image->GetHeight(); + m_width = image->GetWidth(); + int32_t halfsize = initSize >> 1; + m_leftInit = x - halfsize; + m_rightInit = x + halfsize; + m_upInit = y - halfsize; + m_downInit = y + halfsize; +} +CBC_WhiteRectangleDetector::~CBC_WhiteRectangleDetector() {} +CFX_PtrArray* CBC_WhiteRectangleDetector::Detect(int32_t& e) { + int32_t left = m_leftInit; + int32_t right = m_rightInit; + int32_t up = m_upInit; + int32_t down = m_downInit; + FX_BOOL sizeExceeded = FALSE; + FX_BOOL aBlackPointFoundOnBorder = TRUE; + FX_BOOL atLeastOneBlackPointFoundOnBorder = FALSE; + while (aBlackPointFoundOnBorder) { + aBlackPointFoundOnBorder = FALSE; + FX_BOOL rightBorderNotWhite = TRUE; + while (rightBorderNotWhite && right < m_width) { + rightBorderNotWhite = ContainsBlackPoint(up, down, right, FALSE); + if (rightBorderNotWhite) { + right++; + aBlackPointFoundOnBorder = TRUE; + } + } + if (right >= m_width) { + sizeExceeded = TRUE; + break; + } + FX_BOOL bottomBorderNotWhite = TRUE; + while (bottomBorderNotWhite && down < m_height) { + bottomBorderNotWhite = ContainsBlackPoint(left, right, down, TRUE); + if (bottomBorderNotWhite) { + down++; + aBlackPointFoundOnBorder = TRUE; + } + } + if (down >= m_height) { + sizeExceeded = TRUE; + break; + } + FX_BOOL leftBorderNotWhite = TRUE; + while (leftBorderNotWhite && left >= 0) { + leftBorderNotWhite = ContainsBlackPoint(up, down, left, FALSE); + if (leftBorderNotWhite) { + left--; + aBlackPointFoundOnBorder = TRUE; + } + } + if (left < 0) { + sizeExceeded = TRUE; + break; + } + FX_BOOL topBorderNotWhite = TRUE; + while (topBorderNotWhite && up >= 0) { + topBorderNotWhite = ContainsBlackPoint(left, right, up, TRUE); + if (topBorderNotWhite) { + up--; + aBlackPointFoundOnBorder = TRUE; + } + } + if (up < 0) { + sizeExceeded = TRUE; + break; + } + if (aBlackPointFoundOnBorder) { + atLeastOneBlackPointFoundOnBorder = TRUE; + } + } + if (!sizeExceeded && atLeastOneBlackPointFoundOnBorder) { + int32_t maxSize = right - left; + std::unique_ptr<CBC_ResultPoint> z; + for (int32_t i = 1; i < maxSize; i++) { + z.reset(GetBlackPointOnSegment((FX_FLOAT)left, (FX_FLOAT)(down - i), + (FX_FLOAT)(left + i), (FX_FLOAT)(down))); + if (z) + break; + } + if (z.get() == NULL) { + e = BCExceptionNotFound; + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + } + std::unique_ptr<CBC_ResultPoint> t; + for (int32_t j = 1; j < maxSize; j++) { + t.reset(GetBlackPointOnSegment((FX_FLOAT)left, (FX_FLOAT)(up + j), + (FX_FLOAT)(left + j), (FX_FLOAT)up)); + if (t) + break; + } + if (t.get() == NULL) { + e = BCExceptionNotFound; + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + } + std::unique_ptr<CBC_ResultPoint> x; + for (int32_t k = 1; k < maxSize; k++) { + x.reset(GetBlackPointOnSegment((FX_FLOAT)right, (FX_FLOAT)(up + k), + (FX_FLOAT)(right - k), (FX_FLOAT)up)); + if (x) + break; + } + if (x.get() == NULL) { + e = BCExceptionNotFound; + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + } + std::unique_ptr<CBC_ResultPoint> y; + for (int32_t m = 1; m < maxSize; m++) { + y.reset(GetBlackPointOnSegment((FX_FLOAT)right, (FX_FLOAT)(down - m), + (FX_FLOAT)(right - m), (FX_FLOAT)down)); + if (y) + break; + } + if (y.get() == NULL) { + e = BCExceptionNotFound; + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + } + return CenterEdges(y.get(), z.get(), x.get(), t.get()); + } else { + e = BCExceptionNotFound; + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + } + return NULL; +} +int32_t CBC_WhiteRectangleDetector::Round(FX_FLOAT d) { + return (int32_t)(d + 0.5f); +} +CBC_ResultPoint* CBC_WhiteRectangleDetector::GetBlackPointOnSegment( + FX_FLOAT aX, + FX_FLOAT aY, + FX_FLOAT bX, + FX_FLOAT bY) { + int32_t dist = DistanceL2(aX, aY, bX, bY); + float xStep = (bX - aX) / dist; + float yStep = (bY - aY) / dist; + for (int32_t i = 0; i < dist; i++) { + int32_t x = Round(aX + i * xStep); + int32_t y = Round(aY + i * yStep); + if (m_image->Get(x, y)) { + return new CBC_ResultPoint((FX_FLOAT)x, (FX_FLOAT)y); + } + } + return NULL; +} +int32_t CBC_WhiteRectangleDetector::DistanceL2(FX_FLOAT aX, + FX_FLOAT aY, + FX_FLOAT bX, + FX_FLOAT bY) { + float xDiff = aX - bX; + float yDiff = aY - bY; + return Round((float)sqrt(xDiff * xDiff + yDiff * yDiff)); +} +CFX_PtrArray* CBC_WhiteRectangleDetector::CenterEdges(CBC_ResultPoint* y, + CBC_ResultPoint* z, + CBC_ResultPoint* x, + CBC_ResultPoint* t) { + float yi = y->GetX(); + float yj = y->GetY(); + float zi = z->GetX(); + float zj = z->GetY(); + float xi = x->GetX(); + float xj = x->GetY(); + float ti = t->GetX(); + float tj = t->GetY(); + if (yi < m_width / 2) { + CFX_PtrArray* result = new CFX_PtrArray; + result->SetSize(4); + (*result)[0] = new CBC_ResultPoint(ti - CORR, tj + CORR); + (*result)[1] = new CBC_ResultPoint(zi + CORR, zj + CORR); + (*result)[2] = new CBC_ResultPoint(xi - CORR, xj - CORR); + (*result)[3] = new CBC_ResultPoint(yi + CORR, yj - CORR); + return result; + } else { + CFX_PtrArray* result = new CFX_PtrArray; + result->SetSize(4); + (*result)[0] = new CBC_ResultPoint(ti + CORR, tj + CORR); + (*result)[1] = new CBC_ResultPoint(zi + CORR, zj - CORR); + (*result)[2] = new CBC_ResultPoint(xi - CORR, xj + CORR); + (*result)[3] = new CBC_ResultPoint(yi - CORR, yj - CORR); + return result; + } +} +FX_BOOL CBC_WhiteRectangleDetector::ContainsBlackPoint(int32_t a, + int32_t b, + int32_t fixed, + FX_BOOL horizontal) { + if (horizontal) { + for (int32_t x = a; x <= b; x++) { + if (m_image->Get(x, fixed)) { + return TRUE; + } + } + } else { + for (int32_t y = a; y <= b; y++) { + if (m_image->Get(fixed, y)) { + return TRUE; + } + } + } + return FALSE; +} diff --git a/xfa/fxbarcode/common/BC_WhiteRectangleDetector.h b/xfa/fxbarcode/common/BC_WhiteRectangleDetector.h new file mode 100644 index 0000000000..3d6c01ceff --- /dev/null +++ b/xfa/fxbarcode/common/BC_WhiteRectangleDetector.h @@ -0,0 +1,54 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef XFA_FXBARCODE_COMMON_BC_WHITERECTANGLEDETECTOR_H_ +#define XFA_FXBARCODE_COMMON_BC_WHITERECTANGLEDETECTOR_H_ + +#include "core/include/fxcrt/fx_basic.h" + +class CBC_CommonBitMatrix; +class CBC_ResultPoint; + +class CBC_WhiteRectangleDetector { + public: + CBC_WhiteRectangleDetector(CBC_CommonBitMatrix* image); + CBC_WhiteRectangleDetector(CBC_CommonBitMatrix* image, + int32_t initSize, + int32_t x, + int32_t y); + virtual ~CBC_WhiteRectangleDetector(); + CFX_PtrArray* Detect(int32_t& e); + virtual void Init(int32_t& e); + + private: + int32_t Round(float d); + CBC_ResultPoint* GetBlackPointOnSegment(FX_FLOAT aX, + FX_FLOAT aY, + FX_FLOAT bX, + FX_FLOAT bY); + int32_t DistanceL2(FX_FLOAT aX, FX_FLOAT aY, FX_FLOAT bX, FX_FLOAT bY); + CFX_PtrArray* CenterEdges(CBC_ResultPoint* y, + CBC_ResultPoint* z, + CBC_ResultPoint* x, + CBC_ResultPoint* t); + FX_BOOL ContainsBlackPoint(int32_t a, + int32_t b, + int32_t fixed, + FX_BOOL horizontal); + + static const int32_t INIT_SIZE = 30; + static const int32_t CORR = 1; + + CBC_CommonBitMatrix* m_image; + int32_t m_height; + int32_t m_width; + int32_t m_leftInit; + int32_t m_rightInit; + int32_t m_downInit; + int32_t m_upInit; +}; + +#endif // XFA_FXBARCODE_COMMON_BC_WHITERECTANGLEDETECTOR_H_ diff --git a/xfa/fxbarcode/common/reedsolomon/BC_ReedSolomon.cpp b/xfa/fxbarcode/common/reedsolomon/BC_ReedSolomon.cpp new file mode 100644 index 0000000000..4d986cca26 --- /dev/null +++ b/xfa/fxbarcode/common/reedsolomon/BC_ReedSolomon.cpp @@ -0,0 +1,104 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com +// Original code is licensed as follows: +/* + * Copyright 2007 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "xfa/fxbarcode/common/reedsolomon/BC_ReedSolomon.h" + +#include <memory> + +#include "xfa/fxbarcode/common/reedsolomon/BC_ReedSolomonGF256.h" +#include "xfa/fxbarcode/common/reedsolomon/BC_ReedSolomonGF256Poly.h" + +CBC_ReedSolomonEncoder::CBC_ReedSolomonEncoder(CBC_ReedSolomonGF256* field) { + m_field = field; +} +void CBC_ReedSolomonEncoder::Init() { + m_cachedGenerators.Add(new CBC_ReedSolomonGF256Poly(m_field, 1)); +} +CBC_ReedSolomonGF256Poly* CBC_ReedSolomonEncoder::BuildGenerator(int32_t degree, + int32_t& e) { + if (degree >= m_cachedGenerators.GetSize()) { + CBC_ReedSolomonGF256Poly* lastGenerator = + (CBC_ReedSolomonGF256Poly*)(m_cachedGenerators + [m_cachedGenerators.GetSize() - 1]); + for (int32_t d = m_cachedGenerators.GetSize(); d <= degree; d++) { + CFX_Int32Array temp; + temp.Add(1); + temp.Add(m_field->Exp(d - 1)); + CBC_ReedSolomonGF256Poly temp_poly; + temp_poly.Init(m_field, &temp, e); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + CBC_ReedSolomonGF256Poly* nextGenerator = + lastGenerator->Multiply(&temp_poly, e); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + m_cachedGenerators.Add(nextGenerator); + lastGenerator = nextGenerator; + } + } + return (CBC_ReedSolomonGF256Poly*)(m_cachedGenerators[degree]); +} +void CBC_ReedSolomonEncoder::Encode(CFX_Int32Array* toEncode, + int32_t ecBytes, + int32_t& e) { + if (ecBytes == 0) { + e = BCExceptionNoCorrectionBytes; + BC_EXCEPTION_CHECK_ReturnVoid(e); + } + int32_t dataBytes = toEncode->GetSize() - ecBytes; + if (dataBytes <= 0) { + e = BCExceptionNoDataBytesProvided; + BC_EXCEPTION_CHECK_ReturnVoid(e); + } + CBC_ReedSolomonGF256Poly* generator = BuildGenerator(ecBytes, e); + BC_EXCEPTION_CHECK_ReturnVoid(e); + CFX_Int32Array infoCoefficients; + infoCoefficients.SetSize(dataBytes); + for (int32_t x = 0; x < dataBytes; x++) { + infoCoefficients[x] = toEncode->operator[](x); + } + CBC_ReedSolomonGF256Poly info; + info.Init(m_field, &infoCoefficients, e); + BC_EXCEPTION_CHECK_ReturnVoid(e); + std::unique_ptr<CBC_ReedSolomonGF256Poly> infoTemp( + info.MultiplyByMonomial(ecBytes, 1, e)); + BC_EXCEPTION_CHECK_ReturnVoid(e); + std::unique_ptr<CFX_PtrArray> temp(infoTemp->Divide(generator, e)); + BC_EXCEPTION_CHECK_ReturnVoid(e); + CBC_ReedSolomonGF256Poly* remainder = + (CBC_ReedSolomonGF256Poly*)(temp->operator[](1)); + CFX_Int32Array* coefficients = remainder->GetCoefficients(); + int32_t numZeroCoefficients = ecBytes - coefficients->GetSize(); + for (int32_t i = 0; i < numZeroCoefficients; i++) { + (*toEncode)[dataBytes + i] = 0; + } + for (int32_t y = 0; y < coefficients->GetSize(); y++) { + (*toEncode)[dataBytes + numZeroCoefficients + y] = + coefficients->operator[](y); + } + for (int32_t k = 0; k < temp->GetSize(); k++) { + delete (CBC_ReedSolomonGF256Poly*)(*temp)[k]; + } +} +CBC_ReedSolomonEncoder::~CBC_ReedSolomonEncoder() { + for (int32_t i = 0; i < m_cachedGenerators.GetSize(); i++) { + delete (CBC_ReedSolomonGF256Poly*)m_cachedGenerators[i]; + } +} diff --git a/xfa/fxbarcode/common/reedsolomon/BC_ReedSolomon.h b/xfa/fxbarcode/common/reedsolomon/BC_ReedSolomon.h new file mode 100644 index 0000000000..6f6aef7e7d --- /dev/null +++ b/xfa/fxbarcode/common/reedsolomon/BC_ReedSolomon.h @@ -0,0 +1,29 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef XFA_FXBARCODE_COMMON_REEDSOLOMON_BC_REEDSOLOMON_H_ +#define XFA_FXBARCODE_COMMON_REEDSOLOMON_BC_REEDSOLOMON_H_ + +#include "core/include/fxcrt/fx_basic.h" + +class CBC_ReedSolomonGF256; +class CBC_ReedSolomonGF256Poly; + +class CBC_ReedSolomonEncoder { + private: + CBC_ReedSolomonGF256* m_field; + CFX_PtrArray m_cachedGenerators; + CBC_ReedSolomonGF256Poly* BuildGenerator(int32_t degree, int32_t& e); + + public: + CBC_ReedSolomonEncoder(CBC_ReedSolomonGF256* field); + virtual ~CBC_ReedSolomonEncoder(); + + void Encode(CFX_Int32Array* toEncode, int32_t ecBytes, int32_t& e); + virtual void Init(); +}; + +#endif // XFA_FXBARCODE_COMMON_REEDSOLOMON_BC_REEDSOLOMON_H_ diff --git a/xfa/fxbarcode/common/reedsolomon/BC_ReedSolomonDecoder.cpp b/xfa/fxbarcode/common/reedsolomon/BC_ReedSolomonDecoder.cpp new file mode 100644 index 0000000000..ff91c9ddc3 --- /dev/null +++ b/xfa/fxbarcode/common/reedsolomon/BC_ReedSolomonDecoder.cpp @@ -0,0 +1,221 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com +// Original code is licensed as follows: +/* + * Copyright 2007 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "xfa/fxbarcode/common/reedsolomon/BC_ReedSolomonDecoder.h" + +#include <memory> +#include <utility> + +#include "xfa/fxbarcode/common/reedsolomon/BC_ReedSolomonGF256.h" +#include "xfa/fxbarcode/common/reedsolomon/BC_ReedSolomonGF256Poly.h" + +CBC_ReedSolomonDecoder::CBC_ReedSolomonDecoder(CBC_ReedSolomonGF256* field) { + m_field = field; +} +CBC_ReedSolomonDecoder::~CBC_ReedSolomonDecoder() {} +void CBC_ReedSolomonDecoder::Decode(CFX_Int32Array* received, + int32_t twoS, + int32_t& e) { + CBC_ReedSolomonGF256Poly poly; + poly.Init(m_field, received, e); + BC_EXCEPTION_CHECK_ReturnVoid(e); + CFX_Int32Array syndromeCoefficients; + syndromeCoefficients.SetSize(twoS); + FX_BOOL dataMatrix = FALSE; + FX_BOOL noError = TRUE; + for (int32_t i = 0; i < twoS; i++) { + int32_t eval = poly.EvaluateAt(m_field->Exp(dataMatrix ? i + 1 : i)); + syndromeCoefficients[twoS - 1 - i] = eval; + if (eval != 0) { + noError = FALSE; + } + } + if (noError) { + return; + } + CBC_ReedSolomonGF256Poly syndrome; + syndrome.Init(m_field, &syndromeCoefficients, e); + BC_EXCEPTION_CHECK_ReturnVoid(e); + std::unique_ptr<CBC_ReedSolomonGF256Poly> temp( + m_field->BuildMonomial(twoS, 1, e)); + BC_EXCEPTION_CHECK_ReturnVoid(e); + std::unique_ptr<CFX_PtrArray> sigmaOmega( + RunEuclideanAlgorithm(temp.get(), &syndrome, twoS, e)); + BC_EXCEPTION_CHECK_ReturnVoid(e); + std::unique_ptr<CBC_ReedSolomonGF256Poly> sigma( + (CBC_ReedSolomonGF256Poly*)(*sigmaOmega)[0]); + std::unique_ptr<CBC_ReedSolomonGF256Poly> omega( + (CBC_ReedSolomonGF256Poly*)(*sigmaOmega)[1]); + std::unique_ptr<CFX_Int32Array> errorLocations( + FindErrorLocations(sigma.get(), e)); + BC_EXCEPTION_CHECK_ReturnVoid(e); + std::unique_ptr<CFX_Int32Array> errorMagnitudes( + FindErrorMagnitudes(omega.get(), errorLocations.get(), dataMatrix, e)); + BC_EXCEPTION_CHECK_ReturnVoid(e); + for (int32_t k = 0; k < errorLocations->GetSize(); k++) { + int32_t position = + received->GetSize() - 1 - m_field->Log((*errorLocations)[k], e); + BC_EXCEPTION_CHECK_ReturnVoid(e); + if (position < 0) { + e = BCExceptionBadErrorLocation; + BC_EXCEPTION_CHECK_ReturnVoid(e); + } + (*received)[position] = CBC_ReedSolomonGF256::AddOrSubtract( + (*received)[position], (*errorMagnitudes)[k]); + } +} +CFX_PtrArray* CBC_ReedSolomonDecoder::RunEuclideanAlgorithm( + CBC_ReedSolomonGF256Poly* a, + CBC_ReedSolomonGF256Poly* b, + int32_t R, + int32_t& e) { + if (a->GetDegree() < b->GetDegree()) { + CBC_ReedSolomonGF256Poly* temp = a; + a = b; + b = temp; + } + std::unique_ptr<CBC_ReedSolomonGF256Poly> rLast(a->Clone(e)); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + std::unique_ptr<CBC_ReedSolomonGF256Poly> r(b->Clone(e)); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + std::unique_ptr<CBC_ReedSolomonGF256Poly> sLast(m_field->GetOne()->Clone(e)); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + std::unique_ptr<CBC_ReedSolomonGF256Poly> s(m_field->GetZero()->Clone(e)); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + std::unique_ptr<CBC_ReedSolomonGF256Poly> tLast(m_field->GetZero()->Clone(e)); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + std::unique_ptr<CBC_ReedSolomonGF256Poly> t(m_field->GetOne()->Clone(e)); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + while (r->GetDegree() >= R / 2) { + std::unique_ptr<CBC_ReedSolomonGF256Poly> rLastLast = std::move(rLast); + std::unique_ptr<CBC_ReedSolomonGF256Poly> sLastLast = std::move(sLast); + std::unique_ptr<CBC_ReedSolomonGF256Poly> tLastlast = std::move(tLast); + rLast = std::move(r); + sLast = std::move(s); + tLast = std::move(t); + if (rLast->IsZero()) { + e = BCExceptionR_I_1IsZero; + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + } + r.reset(rLastLast->Clone(e)); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + std::unique_ptr<CBC_ReedSolomonGF256Poly> q(m_field->GetZero()->Clone(e)); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + int32_t denominatorLeadingTerm = rLast->GetCoefficients(rLast->GetDegree()); + int32_t dltInverse = m_field->Inverse(denominatorLeadingTerm, e); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + while (r->GetDegree() >= rLast->GetDegree() && !(r->IsZero())) { + int32_t degreeDiff = r->GetDegree() - rLast->GetDegree(); + int32_t scale = + m_field->Multiply(r->GetCoefficients(r->GetDegree()), dltInverse); + std::unique_ptr<CBC_ReedSolomonGF256Poly> build( + m_field->BuildMonomial(degreeDiff, scale, e)); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + q.reset(q->AddOrSubtract(build.get(), e)); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + std::unique_ptr<CBC_ReedSolomonGF256Poly> multiply( + rLast->MultiplyByMonomial(degreeDiff, scale, e)); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + r.reset(r->AddOrSubtract(multiply.get(), e)); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + } + std::unique_ptr<CBC_ReedSolomonGF256Poly> temp1( + q->Multiply(sLast.get(), e)); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + s.reset(temp1->AddOrSubtract(sLastLast.get(), e)); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + std::unique_ptr<CBC_ReedSolomonGF256Poly> temp5( + q->Multiply(tLast.get(), e)); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + t.reset(temp5->AddOrSubtract(tLastlast.get(), e)); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + } + int32_t sigmaTildeAtZero = t->GetCoefficients(0); + if (sigmaTildeAtZero == 0) { + e = BCExceptionIsZero; + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + } + int32_t inverse = m_field->Inverse(sigmaTildeAtZero, e); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + std::unique_ptr<CBC_ReedSolomonGF256Poly> sigma(t->Multiply(inverse, e)); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + std::unique_ptr<CBC_ReedSolomonGF256Poly> omega(r->Multiply(inverse, e)); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + CFX_PtrArray* temp = new CFX_PtrArray; + temp->Add(sigma.release()); + temp->Add(omega.release()); + return temp; +} +CFX_Int32Array* CBC_ReedSolomonDecoder::FindErrorLocations( + CBC_ReedSolomonGF256Poly* errorLocator, + int32_t& e) { + int32_t numErrors = errorLocator->GetDegree(); + if (numErrors == 1) { + std::unique_ptr<CFX_Int32Array> temp(new CFX_Int32Array); + temp->Add(errorLocator->GetCoefficients(1)); + return temp.release(); + } + CFX_Int32Array* tempT = new CFX_Int32Array; + tempT->SetSize(numErrors); + std::unique_ptr<CFX_Int32Array> result(tempT); + int32_t ie = 0; + for (int32_t i = 1; i < 256 && ie < numErrors; i++) { + if (errorLocator->EvaluateAt(i) == 0) { + (*result)[ie] = m_field->Inverse(i, ie); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + ie++; + } + } + if (ie != numErrors) { + e = BCExceptionDegreeNotMatchRoots; + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + } + return result.release(); +} +CFX_Int32Array* CBC_ReedSolomonDecoder::FindErrorMagnitudes( + CBC_ReedSolomonGF256Poly* errorEvaluator, + CFX_Int32Array* errorLocations, + FX_BOOL dataMatrix, + int32_t& e) { + int32_t s = errorLocations->GetSize(); + CFX_Int32Array* temp = new CFX_Int32Array; + temp->SetSize(s); + std::unique_ptr<CFX_Int32Array> result(temp); + for (int32_t i = 0; i < s; i++) { + int32_t xiInverse = m_field->Inverse(errorLocations->operator[](i), e); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + int32_t denominator = 1; + for (int32_t j = 0; j < s; j++) { + if (i != j) { + denominator = m_field->Multiply( + denominator, CBC_ReedSolomonGF256::AddOrSubtract( + 1, m_field->Multiply(errorLocations->operator[](j), + xiInverse))); + } + } + int32_t temp = m_field->Inverse(denominator, temp); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + (*result)[i] = + m_field->Multiply(errorEvaluator->EvaluateAt(xiInverse), temp); + } + return result.release(); +} diff --git a/xfa/fxbarcode/common/reedsolomon/BC_ReedSolomonDecoder.h b/xfa/fxbarcode/common/reedsolomon/BC_ReedSolomonDecoder.h new file mode 100644 index 0000000000..ec14344fe0 --- /dev/null +++ b/xfa/fxbarcode/common/reedsolomon/BC_ReedSolomonDecoder.h @@ -0,0 +1,35 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef XFA_FXBARCODE_COMMON_REEDSOLOMON_BC_REEDSOLOMONDECODER_H_ +#define XFA_FXBARCODE_COMMON_REEDSOLOMON_BC_REEDSOLOMONDECODER_H_ + +#include "core/include/fxcrt/fx_basic.h" + +class CBC_ReedSolomonGF256; +class CBC_ReedSolomonGF256Poly; + +class CBC_ReedSolomonDecoder { + private: + CBC_ReedSolomonGF256* m_field; + + public: + CBC_ReedSolomonDecoder(CBC_ReedSolomonGF256* field); + virtual ~CBC_ReedSolomonDecoder(); + void Decode(CFX_Int32Array* received, int32_t twoS, int32_t& e); + CFX_PtrArray* RunEuclideanAlgorithm(CBC_ReedSolomonGF256Poly* a, + CBC_ReedSolomonGF256Poly* b, + int32_t R, + int32_t& e); + CFX_Int32Array* FindErrorLocations(CBC_ReedSolomonGF256Poly* errorLocator, + int32_t& e); + CFX_Int32Array* FindErrorMagnitudes(CBC_ReedSolomonGF256Poly* errorEvaluator, + CFX_Int32Array* errorLocations, + FX_BOOL dataMatrix, + int32_t& e); +}; + +#endif // XFA_FXBARCODE_COMMON_REEDSOLOMON_BC_REEDSOLOMONDECODER_H_ diff --git a/xfa/fxbarcode/common/reedsolomon/BC_ReedSolomonGF256.cpp b/xfa/fxbarcode/common/reedsolomon/BC_ReedSolomonGF256.cpp new file mode 100644 index 0000000000..5e9fd33ac4 --- /dev/null +++ b/xfa/fxbarcode/common/reedsolomon/BC_ReedSolomonGF256.cpp @@ -0,0 +1,124 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com +// Original code is licensed as follows: +/* + * Copyright 2007 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "xfa/fxbarcode/common/reedsolomon/BC_ReedSolomonGF256.h" +#include "xfa/fxbarcode/common/reedsolomon/BC_ReedSolomonGF256Poly.h" + +CBC_ReedSolomonGF256* CBC_ReedSolomonGF256::QRCodeFild = NULL; +CBC_ReedSolomonGF256* CBC_ReedSolomonGF256::DataMatrixField = NULL; +void CBC_ReedSolomonGF256::Initialize() { + QRCodeFild = new CBC_ReedSolomonGF256(0x011D); + QRCodeFild->Init(); + DataMatrixField = new CBC_ReedSolomonGF256(0x012D); + DataMatrixField->Init(); +} +void CBC_ReedSolomonGF256::Finalize() { + if (QRCodeFild) { + delete QRCodeFild; + } + QRCodeFild = NULL; + if (DataMatrixField) { + delete DataMatrixField; + } + DataMatrixField = NULL; +} +CBC_ReedSolomonGF256::CBC_ReedSolomonGF256(int32_t primitive) { + int32_t x = 1; + for (int32_t j = 0; j < 256; j++) { + m_expTable[j] = x; + x <<= 1; + if (x >= 0x100) { + x ^= primitive; + } + } + for (int32_t i = 0; i < 255; i++) { + m_logTable[m_expTable[i]] = i; + } + m_logTable[0] = 0; +} +void CBC_ReedSolomonGF256::Init() { + m_zero = new CBC_ReedSolomonGF256Poly(this, 0); + m_one = new CBC_ReedSolomonGF256Poly(this, 1); +} +CBC_ReedSolomonGF256::~CBC_ReedSolomonGF256() { + delete m_zero; + delete m_one; +} +CBC_ReedSolomonGF256Poly* CBC_ReedSolomonGF256::GetZero() { + return m_zero; +} +CBC_ReedSolomonGF256Poly* CBC_ReedSolomonGF256::GetOne() { + return m_one; +} +CBC_ReedSolomonGF256Poly* CBC_ReedSolomonGF256::BuildMonomial( + int32_t degree, + int32_t coefficient, + int32_t& e) { + if (degree < 0) { + e = BCExceptionDegreeIsNegative; + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + } + if (coefficient == 0) { + CBC_ReedSolomonGF256Poly* temp = m_zero->Clone(e); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + return temp; + } + CFX_Int32Array coefficients; + coefficients.SetSize(degree + 1); + coefficients[0] = coefficient; + CBC_ReedSolomonGF256Poly* temp = new CBC_ReedSolomonGF256Poly(); + temp->Init(this, &coefficients, e); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + return temp; +} +int32_t CBC_ReedSolomonGF256::AddOrSubtract(int32_t a, int32_t b) { + return a ^ b; +} +int32_t CBC_ReedSolomonGF256::Exp(int32_t a) { + return m_expTable[a]; +} +int32_t CBC_ReedSolomonGF256::Log(int32_t a, int32_t& e) { + if (a == 0) { + e = BCExceptionAIsZero; + BC_EXCEPTION_CHECK_ReturnValue(e, 0); + } + return m_logTable[a]; +} +int32_t CBC_ReedSolomonGF256::Inverse(int32_t a, int32_t& e) { + if (a == 0) { + e = BCExceptionAIsZero; + BC_EXCEPTION_CHECK_ReturnValue(e, 0); + } + return m_expTable[255 - m_logTable[a]]; +} +int32_t CBC_ReedSolomonGF256::Multiply(int32_t a, int32_t b) { + if (a == 0 || b == 0) { + return 0; + } + if (a == 1) { + return b; + } + if (b == 1) { + return a; + } + return m_expTable[(m_logTable[a] + m_logTable[b]) % 255]; +} diff --git a/xfa/fxbarcode/common/reedsolomon/BC_ReedSolomonGF256.h b/xfa/fxbarcode/common/reedsolomon/BC_ReedSolomonGF256.h new file mode 100644 index 0000000000..099cab57d5 --- /dev/null +++ b/xfa/fxbarcode/common/reedsolomon/BC_ReedSolomonGF256.h @@ -0,0 +1,41 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef XFA_FXBARCODE_COMMON_REEDSOLOMON_BC_REEDSOLOMONGF256_H_ +#define XFA_FXBARCODE_COMMON_REEDSOLOMON_BC_REEDSOLOMONGF256_H_ + +#include "core/include/fxcrt/fx_basic.h" +#include "xfa/fxbarcode/utils.h" + +class CBC_ReedSolomonGF256Poly; +class CBC_ReedSolomonGF256 { + public: + static void Initialize(); + static void Finalize(); + static CBC_ReedSolomonGF256* QRCodeFild; + static CBC_ReedSolomonGF256* DataMatrixField; + CBC_ReedSolomonGF256(int32_t primitive); + virtual ~CBC_ReedSolomonGF256(); + CBC_ReedSolomonGF256Poly* GetZero(); + CBC_ReedSolomonGF256Poly* GetOne(); + CBC_ReedSolomonGF256Poly* BuildMonomial(int32_t degree, + int32_t coefficient, + int32_t& e); + static int32_t AddOrSubtract(int32_t a, int32_t b); + int32_t Exp(int32_t a); + int32_t Log(int32_t a, int32_t& e); + int32_t Inverse(int32_t a, int32_t& e); + int32_t Multiply(int32_t a, int32_t b); + virtual void Init(); + + private: + int32_t m_expTable[256]; + int32_t m_logTable[256]; + CBC_ReedSolomonGF256Poly* m_zero; + CBC_ReedSolomonGF256Poly* m_one; +}; + +#endif // XFA_FXBARCODE_COMMON_REEDSOLOMON_BC_REEDSOLOMONGF256_H_ diff --git a/xfa/fxbarcode/common/reedsolomon/BC_ReedSolomonGF256Poly.cpp b/xfa/fxbarcode/common/reedsolomon/BC_ReedSolomonGF256Poly.cpp new file mode 100644 index 0000000000..ee22390df6 --- /dev/null +++ b/xfa/fxbarcode/common/reedsolomon/BC_ReedSolomonGF256Poly.cpp @@ -0,0 +1,254 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com +// Original code is licensed as follows: +/* + * Copyright 2007 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "xfa/fxbarcode/common/reedsolomon/BC_ReedSolomonGF256Poly.h" + +#include <memory> + +#include "xfa/fxbarcode/common/reedsolomon/BC_ReedSolomonGF256.h" + +CBC_ReedSolomonGF256Poly::CBC_ReedSolomonGF256Poly(CBC_ReedSolomonGF256* field, + int32_t coefficients) { + if (field == NULL) { + return; + } + m_field = field; + m_coefficients.Add(coefficients); +} +CBC_ReedSolomonGF256Poly::CBC_ReedSolomonGF256Poly() { + m_field = NULL; +} +void CBC_ReedSolomonGF256Poly::Init(CBC_ReedSolomonGF256* field, + CFX_Int32Array* coefficients, + int32_t& e) { + if (coefficients == NULL || coefficients->GetSize() == 0) { + e = BCExceptionCoefficientsSizeIsNull; + BC_EXCEPTION_CHECK_ReturnVoid(e); + } + m_field = field; + int32_t coefficientsLength = coefficients->GetSize(); + if ((coefficientsLength > 1 && (*coefficients)[0] == 0)) { + int32_t firstNonZero = 1; + while ((firstNonZero < coefficientsLength) && + ((*coefficients)[firstNonZero] == 0)) { + firstNonZero++; + } + if (firstNonZero == coefficientsLength) { + m_coefficients.Copy(*(m_field->GetZero()->GetCoefficients())); + } else { + m_coefficients.SetSize(coefficientsLength - firstNonZero); + for (int32_t i = firstNonZero, j = 0; i < coefficientsLength; i++, j++) { + m_coefficients[j] = coefficients->operator[](i); + } + } + } else { + m_coefficients.Copy(*coefficients); + } +} +CFX_Int32Array* CBC_ReedSolomonGF256Poly::GetCoefficients() { + return &m_coefficients; +} +int32_t CBC_ReedSolomonGF256Poly::GetDegree() { + return m_coefficients.GetSize() - 1; +} +FX_BOOL CBC_ReedSolomonGF256Poly::IsZero() { + return m_coefficients[0] == 0; +} +int32_t CBC_ReedSolomonGF256Poly::GetCoefficients(int32_t degree) { + return m_coefficients[m_coefficients.GetSize() - 1 - degree]; +} +int32_t CBC_ReedSolomonGF256Poly::EvaluateAt(int32_t a) { + if (a == 0) { + return GetCoefficients(0); + } + int32_t size = m_coefficients.GetSize(); + if (a == 1) { + int32_t result = 0; + for (int32_t i = 0; i < size; i++) { + result = CBC_ReedSolomonGF256::AddOrSubtract(result, m_coefficients[i]); + } + return result; + } + int32_t result = m_coefficients[0]; + for (int32_t j = 1; j < size; j++) { + result = CBC_ReedSolomonGF256::AddOrSubtract(m_field->Multiply(a, result), + m_coefficients[j]); + } + return result; +} +CBC_ReedSolomonGF256Poly* CBC_ReedSolomonGF256Poly::Clone(int32_t& e) { + CBC_ReedSolomonGF256Poly* temp = new CBC_ReedSolomonGF256Poly(); + temp->Init(m_field, &m_coefficients, e); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + return temp; +} +CBC_ReedSolomonGF256Poly* CBC_ReedSolomonGF256Poly::AddOrSubtract( + CBC_ReedSolomonGF256Poly* other, + int32_t& e) { + if (IsZero()) { + return other->Clone(e); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + } + if (other->IsZero()) { + return Clone(e); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + } + CFX_Int32Array smallerCoefficients; + smallerCoefficients.Copy(m_coefficients); + CFX_Int32Array largerCoefficients; + largerCoefficients.Copy(*(other->GetCoefficients())); + if (smallerCoefficients.GetSize() > largerCoefficients.GetSize()) { + CFX_Int32Array temp; + temp.Copy(smallerCoefficients); + smallerCoefficients.Copy(largerCoefficients); + largerCoefficients.Copy(temp); + } + CFX_Int32Array sumDiff; + sumDiff.SetSize(largerCoefficients.GetSize()); + int32_t lengthDiff = + largerCoefficients.GetSize() - smallerCoefficients.GetSize(); + for (int32_t i = 0; i < lengthDiff; i++) { + sumDiff[i] = largerCoefficients[i]; + } + for (int32_t j = lengthDiff; j < largerCoefficients.GetSize(); j++) { + sumDiff[j] = (CBC_ReedSolomonGF256::AddOrSubtract( + smallerCoefficients[j - lengthDiff], largerCoefficients[j])); + } + CBC_ReedSolomonGF256Poly* temp = new CBC_ReedSolomonGF256Poly(); + temp->Init(m_field, &sumDiff, e); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + return temp; +} +CBC_ReedSolomonGF256Poly* CBC_ReedSolomonGF256Poly::Multiply( + CBC_ReedSolomonGF256Poly* other, + int32_t& e) { + if (IsZero() || other->IsZero()) { + CBC_ReedSolomonGF256Poly* temp = m_field->GetZero()->Clone(e); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + return temp; + } + CFX_Int32Array aCoefficients; + aCoefficients.Copy(m_coefficients); + int32_t aLength = m_coefficients.GetSize(); + CFX_Int32Array bCoefficients; + bCoefficients.Copy(*(other->GetCoefficients())); + int32_t bLength = other->GetCoefficients()->GetSize(); + CFX_Int32Array product; + product.SetSize(aLength + bLength - 1); + for (int32_t i = 0; i < aLength; i++) { + int32_t aCoeff = m_coefficients[i]; + for (int32_t j = 0; j < bLength; j++) { + product[i + j] = CBC_ReedSolomonGF256::AddOrSubtract( + product[i + j], + m_field->Multiply(aCoeff, other->GetCoefficients()->operator[](j))); + } + } + CBC_ReedSolomonGF256Poly* temp = new CBC_ReedSolomonGF256Poly(); + temp->Init(m_field, &product, e); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + return temp; +} +CBC_ReedSolomonGF256Poly* CBC_ReedSolomonGF256Poly::Multiply(int32_t scalar, + int32_t& e) { + if (scalar == 0) { + CBC_ReedSolomonGF256Poly* temp = m_field->GetZero()->Clone(e); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + return temp; + } + if (scalar == 1) { + return Clone(e); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + } + int32_t size = m_coefficients.GetSize(); + CFX_Int32Array product; + product.SetSize(size); + for (int32_t i = 0; i < size; i++) { + product[i] = m_field->Multiply(m_coefficients[i], scalar); + } + CBC_ReedSolomonGF256Poly* temp = new CBC_ReedSolomonGF256Poly(); + temp->Init(m_field, &product, e); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + return temp; +} +CBC_ReedSolomonGF256Poly* CBC_ReedSolomonGF256Poly::MultiplyByMonomial( + int32_t degree, + int32_t coefficient, + int32_t& e) { + if (degree < 0) { + e = BCExceptionDegreeIsNegative; + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + } + if (coefficient == 0) { + CBC_ReedSolomonGF256Poly* temp = m_field->GetZero()->Clone(e); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + return temp; + } + int32_t size = m_coefficients.GetSize(); + CFX_Int32Array product; + product.SetSize(size + degree); + for (int32_t i = 0; i < size; i++) { + product[i] = (m_field->Multiply(m_coefficients[i], coefficient)); + } + CBC_ReedSolomonGF256Poly* temp = new CBC_ReedSolomonGF256Poly(); + temp->Init(m_field, &product, e); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + return temp; +} +CFX_PtrArray* CBC_ReedSolomonGF256Poly::Divide(CBC_ReedSolomonGF256Poly* other, + int32_t& e) { + if (other->IsZero()) { + e = BCExceptionDivideByZero; + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + } + std::unique_ptr<CBC_ReedSolomonGF256Poly> quotient( + m_field->GetZero()->Clone(e)); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + std::unique_ptr<CBC_ReedSolomonGF256Poly> remainder(Clone(e)); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + int32_t denominatorLeadingTerm = other->GetCoefficients(other->GetDegree()); + int32_t inverseDenominatorLeadingTeam = + m_field->Inverse(denominatorLeadingTerm, e); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + while (remainder->GetDegree() >= other->GetDegree() && !remainder->IsZero()) { + int32_t degreeDifference = remainder->GetDegree() - other->GetDegree(); + int32_t scale = + m_field->Multiply(remainder->GetCoefficients((remainder->GetDegree())), + inverseDenominatorLeadingTeam); + std::unique_ptr<CBC_ReedSolomonGF256Poly> term( + other->MultiplyByMonomial(degreeDifference, scale, e)); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + std::unique_ptr<CBC_ReedSolomonGF256Poly> iteratorQuotient( + m_field->BuildMonomial(degreeDifference, scale, e)); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + quotient.reset(quotient->AddOrSubtract(iteratorQuotient.get(), e)); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + remainder.reset(remainder->AddOrSubtract(term.get(), e)); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + } + CFX_PtrArray* tempPtrA = new CFX_PtrArray; + tempPtrA->Add(quotient.release()); + tempPtrA->Add(remainder.release()); + return tempPtrA; +} +CBC_ReedSolomonGF256Poly::~CBC_ReedSolomonGF256Poly() { + m_coefficients.RemoveAll(); +} diff --git a/xfa/fxbarcode/common/reedsolomon/BC_ReedSolomonGF256Poly.h b/xfa/fxbarcode/common/reedsolomon/BC_ReedSolomonGF256Poly.h new file mode 100644 index 0000000000..16a1f9066e --- /dev/null +++ b/xfa/fxbarcode/common/reedsolomon/BC_ReedSolomonGF256Poly.h @@ -0,0 +1,43 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef XFA_FXBARCODE_COMMON_REEDSOLOMON_BC_REEDSOLOMONGF256POLY_H_ +#define XFA_FXBARCODE_COMMON_REEDSOLOMON_BC_REEDSOLOMONGF256POLY_H_ + +#include "core/include/fxcrt/fx_basic.h" + +class CBC_ReedSolomonGF256; + +class CBC_ReedSolomonGF256Poly { + public: + CBC_ReedSolomonGF256Poly(CBC_ReedSolomonGF256* field, int32_t coefficients); + CBC_ReedSolomonGF256Poly(); + virtual ~CBC_ReedSolomonGF256Poly(); + int32_t GetCoefficients(int32_t degree); + CFX_Int32Array* GetCoefficients(); + int32_t GetDegree(); + FX_BOOL IsZero(); + int32_t EvaluateAt(int32_t a); + CBC_ReedSolomonGF256Poly* AddOrSubtract(CBC_ReedSolomonGF256Poly* other, + int32_t& e); + CBC_ReedSolomonGF256Poly* Multiply(CBC_ReedSolomonGF256Poly* other, + int32_t& e); + CBC_ReedSolomonGF256Poly* Multiply(int32_t scalar, int32_t& e); + CBC_ReedSolomonGF256Poly* MultiplyByMonomial(int32_t degree, + int32_t coefficient, + int32_t& e); + CFX_PtrArray* Divide(CBC_ReedSolomonGF256Poly* other, int32_t& e); + CBC_ReedSolomonGF256Poly* Clone(int32_t& e); + virtual void Init(CBC_ReedSolomonGF256* field, + CFX_Int32Array* coefficients, + int32_t& e); + + private: + CBC_ReedSolomonGF256* m_field; + CFX_Int32Array m_coefficients; +}; + +#endif // XFA_FXBARCODE_COMMON_REEDSOLOMON_BC_REEDSOLOMONGF256POLY_H_ diff --git a/xfa/fxbarcode/datamatrix/BC_ASCIIEncoder.cpp b/xfa/fxbarcode/datamatrix/BC_ASCIIEncoder.cpp new file mode 100644 index 0000000000..00d8fc1615 --- /dev/null +++ b/xfa/fxbarcode/datamatrix/BC_ASCIIEncoder.cpp @@ -0,0 +1,98 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com +// Original code is licensed as follows: +/* + * Copyright 2006-2007 Jeremias Maerki. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "xfa/fxbarcode/BC_Dimension.h" +#include "xfa/fxbarcode/datamatrix/BC_ASCIIEncoder.h" +#include "xfa/fxbarcode/datamatrix/BC_Encoder.h" +#include "xfa/fxbarcode/datamatrix/BC_EncoderContext.h" +#include "xfa/fxbarcode/datamatrix/BC_HighLevelEncoder.h" +#include "xfa/fxbarcode/datamatrix/BC_SymbolInfo.h" +#include "xfa/fxbarcode/datamatrix/BC_SymbolShapeHint.h" + +CBC_ASCIIEncoder::CBC_ASCIIEncoder() {} +CBC_ASCIIEncoder::~CBC_ASCIIEncoder() {} +int32_t CBC_ASCIIEncoder::getEncodingMode() { + return ASCII_ENCODATION; +} +void CBC_ASCIIEncoder::Encode(CBC_EncoderContext& context, int32_t& e) { + int32_t n = CBC_HighLevelEncoder::determineConsecutiveDigitCount( + context.m_msg, context.m_pos); + if (n >= 2) { + FX_WCHAR code = + encodeASCIIDigits(context.m_msg.GetAt(context.m_pos), + context.m_msg.GetAt(context.m_pos + 1), e); + if (e != BCExceptionNO) { + return; + } + context.writeCodeword(code); + context.m_pos += 2; + } else { + FX_WCHAR c = context.getCurrentChar(); + int32_t newMode = CBC_HighLevelEncoder::lookAheadTest( + context.m_msg, context.m_pos, getEncodingMode()); + if (newMode != getEncodingMode()) { + switch (newMode) { + case BASE256_ENCODATION: + context.writeCodeword(CBC_HighLevelEncoder::LATCH_TO_BASE256); + context.signalEncoderChange(BASE256_ENCODATION); + return; + case C40_ENCODATION: + context.writeCodeword(CBC_HighLevelEncoder::LATCH_TO_C40); + context.signalEncoderChange(C40_ENCODATION); + return; + case X12_ENCODATION: + context.writeCodeword(CBC_HighLevelEncoder::LATCH_TO_ANSIX12); + context.signalEncoderChange(X12_ENCODATION); + break; + case TEXT_ENCODATION: + context.writeCodeword(CBC_HighLevelEncoder::LATCH_TO_TEXT); + context.signalEncoderChange(TEXT_ENCODATION); + break; + case EDIFACT_ENCODATION: + context.writeCodeword(CBC_HighLevelEncoder::LATCH_TO_EDIFACT); + context.signalEncoderChange(EDIFACT_ENCODATION); + break; + default: + e = BCExceptionIllegalStateIllegalMode; + return; + } + } else if (CBC_HighLevelEncoder::isExtendedASCII(c)) { + context.writeCodeword(CBC_HighLevelEncoder::UPPER_SHIFT); + context.writeCodeword((FX_WCHAR)(c - 128 + 1)); + context.m_pos++; + } else { + context.writeCodeword((FX_WCHAR)(c + 1)); + context.m_pos++; + } + } +} +FX_WCHAR CBC_ASCIIEncoder::encodeASCIIDigits(FX_WCHAR digit1, + FX_WCHAR digit2, + int32_t& e) { + if (CBC_HighLevelEncoder::isDigit(digit1) && + CBC_HighLevelEncoder::isDigit(digit2)) { + int32_t num = (digit1 - 48) * 10 + (digit2 - 48); + return (FX_WCHAR)(num + 130); + } + e = BCExceptionIllegalArgumentNotGigits; + return 0; +} diff --git a/xfa/fxbarcode/datamatrix/BC_ASCIIEncoder.h b/xfa/fxbarcode/datamatrix/BC_ASCIIEncoder.h new file mode 100644 index 0000000000..11be5e046a --- /dev/null +++ b/xfa/fxbarcode/datamatrix/BC_ASCIIEncoder.h @@ -0,0 +1,27 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef XFA_FXBARCODE_DATAMATRIX_BC_ASCIIENCODER_H_ +#define XFA_FXBARCODE_DATAMATRIX_BC_ASCIIENCODER_H_ + +#include "xfa/fxbarcode/datamatrix/BC_Encoder.h" + +class CBC_EncoderContext; + +class CBC_ASCIIEncoder : public CBC_Encoder { + public: + CBC_ASCIIEncoder(); + virtual ~CBC_ASCIIEncoder(); + int32_t getEncodingMode(); + void Encode(CBC_EncoderContext& context, int32_t& e); + + private: + static FX_WCHAR encodeASCIIDigits(FX_WCHAR digit1, + FX_WCHAR digit2, + int32_t& e); +}; + +#endif // XFA_FXBARCODE_DATAMATRIX_BC_ASCIIENCODER_H_ diff --git a/xfa/fxbarcode/datamatrix/BC_Base256Encoder.cpp b/xfa/fxbarcode/datamatrix/BC_Base256Encoder.cpp new file mode 100644 index 0000000000..98e7848ce8 --- /dev/null +++ b/xfa/fxbarcode/datamatrix/BC_Base256Encoder.cpp @@ -0,0 +1,87 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com +// Original code is licensed as follows: +/* + * Copyright 2006-2007 Jeremias Maerki. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "xfa/fxbarcode/BC_Dimension.h" +#include "xfa/fxbarcode/datamatrix/BC_Base256Encoder.h" +#include "xfa/fxbarcode/datamatrix/BC_Encoder.h" +#include "xfa/fxbarcode/datamatrix/BC_EncoderContext.h" +#include "xfa/fxbarcode/datamatrix/BC_HighLevelEncoder.h" +#include "xfa/fxbarcode/datamatrix/BC_SymbolInfo.h" +#include "xfa/fxbarcode/datamatrix/BC_SymbolShapeHint.h" + +CBC_Base256Encoder::CBC_Base256Encoder() {} +CBC_Base256Encoder::~CBC_Base256Encoder() {} +int32_t CBC_Base256Encoder::getEncodingMode() { + return BASE256_ENCODATION; +} +void CBC_Base256Encoder::Encode(CBC_EncoderContext& context, int32_t& e) { + CFX_WideString buffer; + buffer += (FX_WCHAR)'\0'; + while (context.hasMoreCharacters()) { + FX_WCHAR c = context.getCurrentChar(); + buffer += c; + context.m_pos++; + int32_t newMode = CBC_HighLevelEncoder::lookAheadTest( + context.m_msg, context.m_pos, getEncodingMode()); + if (newMode != getEncodingMode()) { + context.signalEncoderChange(newMode); + break; + } + } + int32_t dataCount = buffer.GetLength() - 1; + FX_CHAR buf[128]; + FXSYS_itoa(dataCount, buf, 10); + buffer.SetAt(0, FX_WCHAR(*buf) - '0'); + int32_t lengthFieldSize = 1; + int32_t currentSize = + context.getCodewordCount() + dataCount + lengthFieldSize; + context.updateSymbolInfo(currentSize, e); + if (e != BCExceptionNO) { + return; + } + FX_BOOL mustPad = (context.m_symbolInfo->m_dataCapacity - currentSize) > 0; + if (context.hasMoreCharacters() || mustPad) { + if (dataCount <= 249) { + buffer.SetAt(0, (FX_WCHAR)dataCount); + } else if (dataCount > 249 && dataCount <= 1555) { + buffer.SetAt(0, (FX_WCHAR)((dataCount / 250) + 249)); + buffer.Insert(1, (FX_WCHAR)(dataCount % 250)); + } else { + e = BCExceptionIllegalStateMessageLengthInvalid; + return; + } + } + for (int32_t i = 0, c = buffer.GetLength(); i < c; i++) { + context.writeCodeword( + randomize255State(buffer.GetAt(i), context.getCodewordCount() + 1)); + } +} +FX_WCHAR CBC_Base256Encoder::randomize255State(FX_WCHAR ch, + int32_t codewordPosition) { + int32_t pseudoRandom = ((149 * codewordPosition) % 255) + 1; + int32_t tempVariable = ch + pseudoRandom; + if (tempVariable <= 255) { + return (FX_WCHAR)tempVariable; + } else { + return (FX_WCHAR)(tempVariable - 256); + } +} diff --git a/xfa/fxbarcode/datamatrix/BC_Base256Encoder.h b/xfa/fxbarcode/datamatrix/BC_Base256Encoder.h new file mode 100644 index 0000000000..64dbdc7ba4 --- /dev/null +++ b/xfa/fxbarcode/datamatrix/BC_Base256Encoder.h @@ -0,0 +1,23 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef XFA_FXBARCODE_DATAMATRIX_BC_BASE256ENCODER_H_ +#define XFA_FXBARCODE_DATAMATRIX_BC_BASE256ENCODER_H_ + +#include "xfa/fxbarcode/datamatrix/BC_Encoder.h" + +class CBC_Base256Encoder : public CBC_Encoder { + public: + CBC_Base256Encoder(); + virtual ~CBC_Base256Encoder(); + int32_t getEncodingMode(); + void Encode(CBC_EncoderContext& context, int32_t& e); + + private: + static FX_WCHAR randomize255State(FX_WCHAR ch, int32_t codewordPosition); +}; + +#endif // XFA_FXBARCODE_DATAMATRIX_BC_BASE256ENCODER_H_ diff --git a/xfa/fxbarcode/datamatrix/BC_C40Encoder.cpp b/xfa/fxbarcode/datamatrix/BC_C40Encoder.cpp new file mode 100644 index 0000000000..8858f60012 --- /dev/null +++ b/xfa/fxbarcode/datamatrix/BC_C40Encoder.cpp @@ -0,0 +1,198 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com +// Original code is licensed as follows: +/* + * Copyright 2006-2007 Jeremias Maerki. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "xfa/fxbarcode/BC_Dimension.h" +#include "xfa/fxbarcode/common/BC_CommonBitMatrix.h" +#include "xfa/fxbarcode/datamatrix/BC_C40Encoder.h" +#include "xfa/fxbarcode/datamatrix/BC_Encoder.h" +#include "xfa/fxbarcode/datamatrix/BC_EncoderContext.h" +#include "xfa/fxbarcode/datamatrix/BC_HighLevelEncoder.h" +#include "xfa/fxbarcode/datamatrix/BC_SymbolInfo.h" +#include "xfa/fxbarcode/datamatrix/BC_SymbolShapeHint.h" + +CBC_C40Encoder::CBC_C40Encoder() {} +CBC_C40Encoder::~CBC_C40Encoder() {} +int32_t CBC_C40Encoder::getEncodingMode() { + return C40_ENCODATION; +} +void CBC_C40Encoder::Encode(CBC_EncoderContext& context, int32_t& e) { + CFX_WideString buffer; + while (context.hasMoreCharacters()) { + FX_WCHAR c = context.getCurrentChar(); + context.m_pos++; + int32_t lastCharSize = encodeChar(c, buffer, e); + if (e != BCExceptionNO) { + return; + } + int32_t unwritten = (buffer.GetLength() / 3) * 2; + int32_t curCodewordCount = context.getCodewordCount() + unwritten; + context.updateSymbolInfo(curCodewordCount, e); + if (e != BCExceptionNO) { + return; + } + int32_t available = context.m_symbolInfo->m_dataCapacity - curCodewordCount; + if (!context.hasMoreCharacters()) { + CFX_WideString removed; + if ((buffer.GetLength() % 3) == 2) { + if (available < 2 || available > 2) { + lastCharSize = + backtrackOneCharacter(context, buffer, removed, lastCharSize, e); + if (e != BCExceptionNO) { + return; + } + } + } + while ((buffer.GetLength() % 3) == 1 && + ((lastCharSize <= 3 && available != 1) || lastCharSize > 3)) { + lastCharSize = + backtrackOneCharacter(context, buffer, removed, lastCharSize, e); + if (e != BCExceptionNO) { + return; + } + } + break; + } + int32_t count = buffer.GetLength(); + if ((count % 3) == 0) { + int32_t newMode = CBC_HighLevelEncoder::lookAheadTest( + context.m_msg, context.m_pos, getEncodingMode()); + if (newMode != getEncodingMode()) { + context.signalEncoderChange(newMode); + break; + } + } + } + handleEOD(context, buffer, e); +} +void CBC_C40Encoder::writeNextTriplet(CBC_EncoderContext& context, + CFX_WideString& buffer) { + context.writeCodewords(encodeToCodewords(buffer, 0)); + buffer.Delete(0, 3); +} +void CBC_C40Encoder::handleEOD(CBC_EncoderContext& context, + CFX_WideString& buffer, + int32_t& e) { + int32_t unwritten = (buffer.GetLength() / 3) * 2; + int32_t rest = buffer.GetLength() % 3; + int32_t curCodewordCount = context.getCodewordCount() + unwritten; + context.updateSymbolInfo(curCodewordCount, e); + if (e != BCExceptionNO) { + return; + } + int32_t available = context.m_symbolInfo->m_dataCapacity - curCodewordCount; + if (rest == 2) { + buffer += (FX_WCHAR)'\0'; + while (buffer.GetLength() >= 3) { + writeNextTriplet(context, buffer); + } + if (context.hasMoreCharacters()) { + context.writeCodeword(CBC_HighLevelEncoder::C40_UNLATCH); + } + } else if (available == 1 && rest == 1) { + while (buffer.GetLength() >= 3) { + writeNextTriplet(context, buffer); + } + if (context.hasMoreCharacters()) { + context.writeCodeword(CBC_HighLevelEncoder::C40_UNLATCH); + } + context.m_pos--; + } else if (rest == 0) { + while (buffer.GetLength() >= 3) { + writeNextTriplet(context, buffer); + } + if (available > 0 || context.hasMoreCharacters()) { + context.writeCodeword(CBC_HighLevelEncoder::C40_UNLATCH); + } + } else { + e = BCExceptionIllegalStateUnexpectedCase; + return; + } + context.signalEncoderChange(ASCII_ENCODATION); +} +int32_t CBC_C40Encoder::encodeChar(FX_WCHAR c, CFX_WideString& sb, int32_t& e) { + if (c == ' ') { + sb += (FX_WCHAR)'\3'; + return 1; + } else if ((c >= '0') && (c <= '9')) { + sb += (FX_WCHAR)(c - 48 + 4); + return 1; + } else if ((c >= 'A') && (c <= 'Z')) { + sb += (FX_WCHAR)(c - 65 + 14); + return 1; + } else if (c <= 0x1f) { + sb += (FX_WCHAR)'\0'; + sb += c; + return 2; + } else if ((c >= '!') && (c <= '/')) { + sb += (FX_WCHAR)'\1'; + sb += (FX_WCHAR)(c - 33); + return 2; + } else if ((c >= ':') && (c <= '@')) { + sb += (FX_WCHAR)'\1'; + sb += (FX_WCHAR)(c - 58 + 15); + return 2; + } else if ((c >= '[') && (c <= '_')) { + sb += (FX_WCHAR)'\1'; + sb += (FX_WCHAR)(c - 91 + 22); + return 2; + } else if ((c >= 60) && (c <= 0x7f)) { + sb += (FX_WCHAR)'\2'; + sb += (FX_WCHAR)(c - 96); + return 2; + } else if (c >= 80) { + sb += (FX_WCHAR)'\1'; + sb += (FX_WCHAR)0x001e; + int32_t len = 2; + len += encodeChar((c - 128), sb, e); + BC_EXCEPTION_CHECK_ReturnValue(e, 0); + return len; + } else { + e = BCExceptionIllegalArgument; + return 0; + } +} +int32_t CBC_C40Encoder::backtrackOneCharacter(CBC_EncoderContext& context, + CFX_WideString& buffer, + CFX_WideString& removed, + int32_t lastCharSize, + int32_t& e) { + int32_t count = buffer.GetLength(); + buffer.Delete(count - lastCharSize, count); + context.m_pos--; + FX_WCHAR c = context.getCurrentChar(); + lastCharSize = encodeChar(c, removed, e); + BC_EXCEPTION_CHECK_ReturnValue(e, -1); + context.resetSymbolInfo(); + return lastCharSize; +} +CFX_WideString CBC_C40Encoder::encodeToCodewords(CFX_WideString sb, + int32_t startPos) { + FX_WCHAR c1 = sb.GetAt(startPos); + FX_WCHAR c2 = sb.GetAt(startPos + 1); + FX_WCHAR c3 = sb.GetAt(startPos + 2); + int32_t v = (1600 * c1) + (40 * c2) + c3 + 1; + FX_WCHAR cw1 = (FX_WCHAR)(v / 256); + FX_WCHAR cw2 = (FX_WCHAR)(v % 256); + CFX_WideString b1(cw1); + CFX_WideString b2(cw2); + return b1 + b2; +} diff --git a/xfa/fxbarcode/datamatrix/BC_C40Encoder.h b/xfa/fxbarcode/datamatrix/BC_C40Encoder.h new file mode 100644 index 0000000000..9dcb1e5c5f --- /dev/null +++ b/xfa/fxbarcode/datamatrix/BC_C40Encoder.h @@ -0,0 +1,34 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef XFA_FXBARCODE_DATAMATRIX_BC_C40ENCODER_H_ +#define XFA_FXBARCODE_DATAMATRIX_BC_C40ENCODER_H_ + +#include "xfa/fxbarcode/datamatrix/BC_Encoder.h" + +class CBC_C40Encoder : public CBC_Encoder { + public: + CBC_C40Encoder(); + virtual ~CBC_C40Encoder(); + virtual int32_t getEncodingMode(); + virtual void Encode(CBC_EncoderContext& context, int32_t& e); + static void writeNextTriplet(CBC_EncoderContext& context, + CFX_WideString& buffer); + virtual void handleEOD(CBC_EncoderContext& context, + CFX_WideString& buffer, + int32_t& e); + virtual int32_t encodeChar(FX_WCHAR c, CFX_WideString& sb, int32_t& e); + + private: + int32_t backtrackOneCharacter(CBC_EncoderContext& context, + CFX_WideString& buffer, + CFX_WideString& removed, + int32_t lastCharSize, + int32_t& e); + static CFX_WideString encodeToCodewords(CFX_WideString sb, int32_t startPos); +}; + +#endif // XFA_FXBARCODE_DATAMATRIX_BC_C40ENCODER_H_ diff --git a/xfa/fxbarcode/datamatrix/BC_DataMatrixBitMatrixParser.cpp b/xfa/fxbarcode/datamatrix/BC_DataMatrixBitMatrixParser.cpp new file mode 100644 index 0000000000..a0c00e9506 --- /dev/null +++ b/xfa/fxbarcode/datamatrix/BC_DataMatrixBitMatrixParser.cpp @@ -0,0 +1,378 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com +// Original code is licensed as follows: +/* + * Copyright 2007 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "xfa/fxbarcode/datamatrix/BC_DataMatrixBitMatrixParser.h" + +#include <memory> + +#include "xfa/fxbarcode/common/BC_CommonBitMatrix.h" +#include "xfa/fxbarcode/datamatrix/BC_DataMatrixVersion.h" +#include "xfa/fxbarcode/utils.h" + +CBC_DataMatrixBitMatrixParser::CBC_DataMatrixBitMatrixParser() { + m_mappingBitMatrix = NULL; + m_version = NULL; + m_readMappingMatrix = NULL; +} +void CBC_DataMatrixBitMatrixParser::Init(CBC_CommonBitMatrix* bitMatrix, + int32_t& e) { + int32_t dimension = bitMatrix->GetHeight(); + if (dimension < 8 || dimension > 144 || (dimension & 0x01) != 0) { + e = BCExceptionFormatException; + return; + } + m_version = ReadVersion(bitMatrix, e); + BC_EXCEPTION_CHECK_ReturnVoid(e); + m_mappingBitMatrix = ExtractDataRegion(bitMatrix, e); + BC_EXCEPTION_CHECK_ReturnVoid(e); + m_readMappingMatrix = new CBC_CommonBitMatrix(); + m_readMappingMatrix->Init(m_mappingBitMatrix->GetWidth(), + m_mappingBitMatrix->GetHeight()); +} +CBC_DataMatrixBitMatrixParser::~CBC_DataMatrixBitMatrixParser() { + delete m_mappingBitMatrix; + delete m_readMappingMatrix; +} +CBC_DataMatrixVersion* CBC_DataMatrixBitMatrixParser::GetVersion() { + return m_version; +} +CBC_DataMatrixVersion* CBC_DataMatrixBitMatrixParser::ReadVersion( + CBC_CommonBitMatrix* bitMatrix, + int32_t& e) { + int32_t rows = bitMatrix->GetHeight(); + int32_t columns = bitMatrix->GetWidth(); + CBC_DataMatrixVersion* temp = + CBC_DataMatrixVersion::GetVersionForDimensions(rows, columns, e); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + return temp; +} +CFX_ByteArray* CBC_DataMatrixBitMatrixParser::ReadCodewords(int32_t& e) { + std::unique_ptr<CFX_ByteArray> result(new CFX_ByteArray()); + result->SetSize(m_version->GetTotalCodewords()); + int32_t resultOffset = 0; + int32_t row = 4; + int32_t column = 0; + int32_t numRows = m_mappingBitMatrix->GetHeight(); + int32_t numColumns = m_mappingBitMatrix->GetWidth(); + FX_BOOL corner1Read = FALSE; + FX_BOOL corner2Read = FALSE; + FX_BOOL corner3Read = FALSE; + FX_BOOL corner4Read = FALSE; + do { + if ((row == numRows) && (column == 0) && !corner1Read) { + (*result)[resultOffset++] = (uint8_t)ReadCorner1(numRows, numColumns); + row -= 2; + column += 2; + corner1Read = TRUE; + } else if ((row == numRows - 2) && (column == 0) && + ((numColumns & 0x03) != 0) && !corner2Read) { + (*result)[resultOffset++] = (uint8_t)ReadCorner2(numRows, numColumns); + row -= 2; + column += 2; + corner2Read = TRUE; + } else if ((row == numRows + 4) && (column == 2) && + ((numColumns & 0x07) == 0) && !corner3Read) { + (*result)[resultOffset++] = (uint8_t)ReadCorner3(numRows, numColumns); + row -= 2; + column += 2; + corner3Read = TRUE; + } else if ((row == numRows - 2) && (column == 0) && + ((numColumns & 0x07) == 4) && !corner4Read) { + (*result)[resultOffset++] = (uint8_t)ReadCorner4(numRows, numColumns); + row -= 2; + column += 2; + corner4Read = TRUE; + } else { + do { + if ((row < numRows) && (column >= 0) && + !m_readMappingMatrix->Get(column, row)) { + if (resultOffset < (*result).GetSize()) { + (*result)[resultOffset++] = + (uint8_t)ReadUtah(row, column, numRows, numColumns); + } + } + row -= 2; + column += 2; + } while ((row >= 0) && (column < numColumns)); + row += 1; + column += 3; + do { + if ((row >= 0) && (column < numColumns) && + !m_readMappingMatrix->Get(column, row)) { + if (resultOffset < (*result).GetSize()) { + (*result)[resultOffset++] = + (uint8_t)ReadUtah(row, column, numRows, numColumns); + } + } + row += 2; + column -= 2; + } while ((row < numRows) && (column >= 0)); + row += 3; + column += 1; + } + } while ((row < numRows) || (column < numColumns)); + if (resultOffset != m_version->GetTotalCodewords()) { + e = BCExceptionFormatException; + return NULL; + } + return result.release(); +} +FX_BOOL CBC_DataMatrixBitMatrixParser::ReadModule(int32_t row, + int32_t column, + int32_t numRows, + int32_t numColumns) { + if (row < 0) { + row += numRows; + column += 4 - ((numRows + 4) & 0x07); + } + if (column < 0) { + column += numColumns; + row += 4 - ((numColumns + 4) & 0x07); + } + m_readMappingMatrix->Set(column, row); + return m_mappingBitMatrix->Get(column, row); +} +int32_t CBC_DataMatrixBitMatrixParser::ReadUtah(int32_t row, + int32_t column, + int32_t numRows, + int32_t numColumns) { + int32_t currentByte = 0; + if (ReadModule(row - 2, column - 2, numRows, numColumns)) { + currentByte |= 1; + } + currentByte <<= 1; + if (ReadModule(row - 2, column - 1, numRows, numColumns)) { + currentByte |= 1; + } + currentByte <<= 1; + if (ReadModule(row - 1, column - 2, numRows, numColumns)) { + currentByte |= 1; + } + currentByte <<= 1; + if (ReadModule(row - 1, column - 1, numRows, numColumns)) { + currentByte |= 1; + } + currentByte <<= 1; + if (ReadModule(row - 1, column, numRows, numColumns)) { + currentByte |= 1; + } + currentByte <<= 1; + if (ReadModule(row, column - 2, numRows, numColumns)) { + currentByte |= 1; + } + currentByte <<= 1; + if (ReadModule(row, column - 1, numRows, numColumns)) { + currentByte |= 1; + } + currentByte <<= 1; + if (ReadModule(row, column, numRows, numColumns)) { + currentByte |= 1; + } + return currentByte; +} +int32_t CBC_DataMatrixBitMatrixParser::ReadCorner1(int32_t numRows, + int32_t numColumns) { + int32_t currentByte = 0; + if (ReadModule(numRows - 1, 0, numRows, numColumns)) { + currentByte |= 1; + } + currentByte <<= 1; + if (ReadModule(numRows - 1, 1, numRows, numColumns)) { + currentByte |= 1; + } + currentByte <<= 1; + if (ReadModule(numRows - 1, 2, numRows, numColumns)) { + currentByte |= 1; + } + currentByte <<= 1; + if (ReadModule(0, numColumns - 2, numRows, numColumns)) { + currentByte |= 1; + } + currentByte <<= 1; + if (ReadModule(0, numColumns - 1, numRows, numColumns)) { + currentByte |= 1; + } + currentByte <<= 1; + if (ReadModule(1, numColumns - 1, numRows, numColumns)) { + currentByte |= 1; + } + currentByte <<= 1; + if (ReadModule(2, numColumns - 1, numRows, numColumns)) { + currentByte |= 1; + } + currentByte <<= 1; + if (ReadModule(3, numColumns - 1, numRows, numColumns)) { + currentByte |= 1; + } + return currentByte; +} +int32_t CBC_DataMatrixBitMatrixParser::ReadCorner2(int32_t numRows, + int32_t numColumns) { + int32_t currentByte = 0; + if (ReadModule(numRows - 3, 0, numRows, numColumns)) { + currentByte |= 1; + } + currentByte <<= 1; + if (ReadModule(numRows - 2, 0, numRows, numColumns)) { + currentByte |= 1; + } + currentByte <<= 1; + if (ReadModule(numRows - 1, 0, numRows, numColumns)) { + currentByte |= 1; + } + currentByte <<= 1; + if (ReadModule(0, numColumns - 4, numRows, numColumns)) { + currentByte |= 1; + } + currentByte <<= 1; + if (ReadModule(0, numColumns - 3, numRows, numColumns)) { + currentByte |= 1; + } + currentByte <<= 1; + if (ReadModule(0, numColumns - 2, numRows, numColumns)) { + currentByte |= 1; + } + currentByte <<= 1; + if (ReadModule(0, numColumns - 1, numRows, numColumns)) { + currentByte |= 1; + } + currentByte <<= 1; + if (ReadModule(1, numColumns - 1, numRows, numColumns)) { + currentByte |= 1; + } + return currentByte; +} +int32_t CBC_DataMatrixBitMatrixParser::ReadCorner3(int32_t numRows, + int32_t numColumns) { + int32_t currentByte = 0; + if (ReadModule(numRows - 1, 0, numRows, numColumns)) { + currentByte |= 1; + } + currentByte <<= 1; + if (ReadModule(numRows - 1, numColumns - 1, numRows, numColumns)) { + currentByte |= 1; + } + currentByte <<= 1; + if (ReadModule(0, numColumns - 3, numRows, numColumns)) { + currentByte |= 1; + } + currentByte <<= 1; + if (ReadModule(0, numColumns - 2, numRows, numColumns)) { + currentByte |= 1; + } + currentByte <<= 1; + if (ReadModule(0, numColumns - 1, numRows, numColumns)) { + currentByte |= 1; + } + currentByte <<= 1; + if (ReadModule(1, numColumns - 3, numRows, numColumns)) { + currentByte |= 1; + } + currentByte <<= 1; + if (ReadModule(1, numColumns - 2, numRows, numColumns)) { + currentByte |= 1; + } + currentByte <<= 1; + if (ReadModule(1, numColumns - 1, numRows, numColumns)) { + currentByte |= 1; + } + return currentByte; +} +int32_t CBC_DataMatrixBitMatrixParser::ReadCorner4(int32_t numRows, + int32_t numColumns) { + int32_t currentByte = 0; + if (ReadModule(numRows - 3, 0, numRows, numColumns)) { + currentByte |= 1; + } + currentByte <<= 1; + if (ReadModule(numRows - 2, 0, numRows, numColumns)) { + currentByte |= 1; + } + currentByte <<= 1; + if (ReadModule(numRows - 1, 0, numRows, numColumns)) { + currentByte |= 1; + } + currentByte <<= 1; + if (ReadModule(0, numColumns - 2, numRows, numColumns)) { + currentByte |= 1; + } + currentByte <<= 1; + if (ReadModule(0, numColumns - 1, numRows, numColumns)) { + currentByte |= 1; + } + currentByte <<= 1; + if (ReadModule(1, numColumns - 1, numRows, numColumns)) { + currentByte |= 1; + } + currentByte <<= 1; + if (ReadModule(2, numColumns - 1, numRows, numColumns)) { + currentByte |= 1; + } + currentByte <<= 1; + if (ReadModule(3, numColumns - 1, numRows, numColumns)) { + currentByte |= 1; + } + return currentByte; +} +CBC_CommonBitMatrix* CBC_DataMatrixBitMatrixParser::ExtractDataRegion( + CBC_CommonBitMatrix* bitMatrix, + int32_t& e) { + int32_t symbolSizeRows = m_version->GetSymbolSizeRows(); + int32_t symbolSizeColumns = m_version->GetSymbolSizeColumns(); + if (bitMatrix->GetHeight() != symbolSizeRows) { + e = BCExceptionCanNotCallGetDimensionOnNonSquareMatrix; + return NULL; + } + int32_t dataRegionSizeRows = m_version->GetDataRegionSizeRows(); + int32_t dataRegionSizeColumns = m_version->GetDataRegionSizeColumns(); + int32_t numDataRegionsRow = symbolSizeRows / dataRegionSizeRows; + int32_t numDataRegionsColumn = symbolSizeColumns / dataRegionSizeColumns; + int32_t sizeDataRegionRow = numDataRegionsRow * dataRegionSizeRows; + int32_t sizeDataRegionColumn = numDataRegionsColumn * dataRegionSizeColumns; + CBC_CommonBitMatrix* bitMatrixWithoutAlignment = new CBC_CommonBitMatrix(); + bitMatrixWithoutAlignment->Init(sizeDataRegionColumn, sizeDataRegionRow); + int32_t dataRegionRow; + for (dataRegionRow = 0; dataRegionRow < numDataRegionsRow; ++dataRegionRow) { + int32_t dataRegionRowOffset = dataRegionRow * dataRegionSizeRows; + int32_t dataRegionColumn; + for (dataRegionColumn = 0; dataRegionColumn < numDataRegionsColumn; + ++dataRegionColumn) { + int32_t dataRegionColumnOffset = dataRegionColumn * dataRegionSizeColumns; + int32_t i; + for (i = 0; i < dataRegionSizeRows; ++i) { + int32_t readRowOffset = + dataRegionRow * (dataRegionSizeRows + 2) + 1 + i; + int32_t writeRowOffset = dataRegionRowOffset + i; + int32_t j; + for (j = 0; j < dataRegionSizeColumns; ++j) { + int32_t readColumnOffset = + dataRegionColumn * (dataRegionSizeColumns + 2) + 1 + j; + if (bitMatrix->Get(readColumnOffset, readRowOffset)) { + int32_t writeColumnOffset = dataRegionColumnOffset + j; + bitMatrixWithoutAlignment->Set(writeColumnOffset, writeRowOffset); + } + } + } + } + } + return bitMatrixWithoutAlignment; +} diff --git a/xfa/fxbarcode/datamatrix/BC_DataMatrixBitMatrixParser.h b/xfa/fxbarcode/datamatrix/BC_DataMatrixBitMatrixParser.h new file mode 100644 index 0000000000..4c54d61eef --- /dev/null +++ b/xfa/fxbarcode/datamatrix/BC_DataMatrixBitMatrixParser.h @@ -0,0 +1,45 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef XFA_FXBARCODE_DATAMATRIX_BC_DATAMATRIXBITMATRIXPARSER_H_ +#define XFA_FXBARCODE_DATAMATRIX_BC_DATAMATRIXBITMATRIXPARSER_H_ + +#include "core/include/fxcrt/fx_basic.h" + +class CBC_CommonBitMatrix; +class CBC_DataMatrixVersion; + +class CBC_DataMatrixBitMatrixParser { + public: + CBC_DataMatrixBitMatrixParser(); + virtual ~CBC_DataMatrixBitMatrixParser(); + CBC_DataMatrixVersion* GetVersion(); + CFX_ByteArray* ReadCodewords(int32_t& e); + FX_BOOL ReadModule(int32_t row, + int32_t column, + int32_t numRows, + int32_t numColumns); + int32_t ReadUtah(int32_t row, + int32_t column, + int32_t numRows, + int32_t numColumns); + int32_t ReadCorner1(int32_t numRows, int32_t numColumns); + int32_t ReadCorner2(int32_t numRows, int32_t numColumns); + int32_t ReadCorner3(int32_t numRows, int32_t numColumns); + int32_t ReadCorner4(int32_t numRows, int32_t numColumns); + CBC_CommonBitMatrix* ExtractDataRegion(CBC_CommonBitMatrix* bitMatrix, + int32_t& e); + virtual void Init(CBC_CommonBitMatrix* bitMatrix, int32_t& e); + + private: + static CBC_DataMatrixVersion* ReadVersion(CBC_CommonBitMatrix* bitMatrix, + int32_t& e); + CBC_CommonBitMatrix* m_mappingBitMatrix; + CBC_CommonBitMatrix* m_readMappingMatrix; + CBC_DataMatrixVersion* m_version; +}; + +#endif // XFA_FXBARCODE_DATAMATRIX_BC_DATAMATRIXBITMATRIXPARSER_H_ diff --git a/xfa/fxbarcode/datamatrix/BC_DataMatrixDataBlock.cpp b/xfa/fxbarcode/datamatrix/BC_DataMatrixDataBlock.cpp new file mode 100644 index 0000000000..89c09c22a8 --- /dev/null +++ b/xfa/fxbarcode/datamatrix/BC_DataMatrixDataBlock.cpp @@ -0,0 +1,115 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com +// Original code is licensed as follows: +/* + * Copyright 2008 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "xfa/fxbarcode/datamatrix/BC_DataMatrixDataBlock.h" + +#include <memory> + +#include "xfa/fxbarcode/datamatrix/BC_DataMatrixVersion.h" +#include "xfa/fxbarcode/utils.h" + +CBC_DataMatrixDataBlock::~CBC_DataMatrixDataBlock() {} +CBC_DataMatrixDataBlock::CBC_DataMatrixDataBlock(int32_t numDataCodewords, + CFX_ByteArray* codewords) { + m_codewords.Copy(*codewords); + m_numDataCodewords = numDataCodewords; +} +CFX_PtrArray* CBC_DataMatrixDataBlock::GetDataBlocks( + CFX_ByteArray* rawCodewords, + CBC_DataMatrixVersion* version, + int32_t& e) { + ECBlocks* ecBlocks = version->GetECBlocks(); + int32_t totalBlocks = 0; + const CFX_PtrArray& ecBlockArray = ecBlocks->GetECBlocks(); + int32_t i; + for (i = 0; i < ecBlockArray.GetSize(); i++) { + totalBlocks += ((ECB*)ecBlockArray[i])->GetCount(); + } + std::unique_ptr<CFX_PtrArray> result(new CFX_PtrArray()); + result->SetSize(totalBlocks); + int32_t numResultBlocks = 0; + int32_t j; + for (j = 0; j < ecBlockArray.GetSize(); j++) { + for (i = 0; i < ((ECB*)ecBlockArray[j])->GetCount(); i++) { + int32_t numDataCodewords = ((ECB*)ecBlockArray[j])->GetDataCodewords(); + int32_t numBlockCodewords = ecBlocks->GetECCodewords() + numDataCodewords; + CFX_ByteArray codewords; + codewords.SetSize(numBlockCodewords); + (*result)[numResultBlocks++] = + new CBC_DataMatrixDataBlock(numDataCodewords, &codewords); + codewords.SetSize(0); + } + } + int32_t longerBlocksTotalCodewords = + ((CBC_DataMatrixDataBlock*)(*result)[0])->GetCodewords()->GetSize(); + int32_t longerBlocksNumDataCodewords = + longerBlocksTotalCodewords - ecBlocks->GetECCodewords(); + int32_t shorterBlocksNumDataCodewords = longerBlocksNumDataCodewords - 1; + int32_t rawCodewordsOffset = 0; + for (i = 0; i < shorterBlocksNumDataCodewords; i++) { + int32_t j; + for (j = 0; j < numResultBlocks; j++) { + if (rawCodewordsOffset < rawCodewords->GetSize()) { + ((CBC_DataMatrixDataBlock*)(*result)[j]) + ->GetCodewords() + -> + operator[](i) = (*rawCodewords)[rawCodewordsOffset++]; + } + } + } + const bool specialVersion = version->GetVersionNumber() == 24; + int32_t numLongerBlocks = specialVersion ? 8 : numResultBlocks; + for (j = 0; j < numLongerBlocks; j++) { + if (rawCodewordsOffset < rawCodewords->GetSize()) { + ((CBC_DataMatrixDataBlock*)(*result)[j]) + ->GetCodewords() + -> + operator[](longerBlocksNumDataCodewords - 1) = + (*rawCodewords)[rawCodewordsOffset++]; + } + } + int32_t max = + ((CBC_DataMatrixDataBlock*)(*result)[0])->GetCodewords()->GetSize(); + for (i = longerBlocksNumDataCodewords; i < max; i++) { + int32_t j; + for (j = 0; j < numResultBlocks; j++) { + int32_t iOffset = specialVersion && j > 7 ? i - 1 : i; + if (rawCodewordsOffset < rawCodewords->GetSize()) { + ((CBC_DataMatrixDataBlock*)(*result)[j]) + ->GetCodewords() + -> + operator[](iOffset) = (*rawCodewords)[rawCodewordsOffset++]; + } + } + } + if (rawCodewordsOffset != rawCodewords->GetSize()) { + e = BCExceptionIllegalArgument; + return NULL; + } + return result.release(); +} +int32_t CBC_DataMatrixDataBlock::GetNumDataCodewords() { + return m_numDataCodewords; +} +CFX_ByteArray* CBC_DataMatrixDataBlock::GetCodewords() { + return &m_codewords; +} diff --git a/xfa/fxbarcode/datamatrix/BC_DataMatrixDataBlock.h b/xfa/fxbarcode/datamatrix/BC_DataMatrixDataBlock.h new file mode 100644 index 0000000000..218bb0bb49 --- /dev/null +++ b/xfa/fxbarcode/datamatrix/BC_DataMatrixDataBlock.h @@ -0,0 +1,32 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef XFA_FXBARCODE_DATAMATRIX_BC_DATAMATRIXDATABLOCK_H_ +#define XFA_FXBARCODE_DATAMATRIX_BC_DATAMATRIXDATABLOCK_H_ + +#include "core/include/fxcrt/fx_basic.h" + +class CBC_DataMatrixVersion; + +class CBC_DataMatrixDataBlock { + public: + virtual ~CBC_DataMatrixDataBlock(); + + int32_t GetNumDataCodewords(); + CFX_ByteArray* GetCodewords(); + + static CFX_PtrArray* GetDataBlocks(CFX_ByteArray* rawCodewords, + CBC_DataMatrixVersion* version, + int32_t& e); + + private: + int32_t m_numDataCodewords; + CFX_ByteArray m_codewords; + + CBC_DataMatrixDataBlock(int32_t numDataCodewords, CFX_ByteArray* codewords); +}; + +#endif // XFA_FXBARCODE_DATAMATRIX_BC_DATAMATRIXDATABLOCK_H_ diff --git a/xfa/fxbarcode/datamatrix/BC_DataMatrixDecodedBitStreamParser.cpp b/xfa/fxbarcode/datamatrix/BC_DataMatrixDecodedBitStreamParser.cpp new file mode 100644 index 0000000000..693b6b9209 --- /dev/null +++ b/xfa/fxbarcode/datamatrix/BC_DataMatrixDecodedBitStreamParser.cpp @@ -0,0 +1,473 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com +// Original code is licensed as follows: +/* + * Copyright 2008 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "xfa/fxbarcode/common/BC_CommonBitSource.h" +#include "xfa/fxbarcode/common/BC_CommonDecoderResult.h" +#include "xfa/fxbarcode/datamatrix/BC_DataMatrixDecodedBitStreamParser.h" + +const FX_CHAR CBC_DataMatrixDecodedBitStreamParser::C40_BASIC_SET_CHARS[] = { + '*', '*', '*', ' ', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', + 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', + 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'}; +const FX_CHAR CBC_DataMatrixDecodedBitStreamParser::C40_SHIFT2_SET_CHARS[] = { + '!', '"', '#', '$', '%', '&', '\'', '(', ')', '*', '+', ',', '-', '.', + '/', ':', ';', '<', '=', '>', '?', '@', '[', '\\', ']', '^', '_'}; +const FX_CHAR CBC_DataMatrixDecodedBitStreamParser::TEXT_BASIC_SET_CHARS[] = { + '*', '*', '*', ' ', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', + 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', + 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'}; +const FX_CHAR CBC_DataMatrixDecodedBitStreamParser::TEXT_SHIFT3_SET_CHARS[] = { + '\'', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', + 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', + 'V', 'W', 'X', 'Y', 'Z', '{', '|', '}', '~', (FX_CHAR)127}; +const int32_t CBC_DataMatrixDecodedBitStreamParser::PAD_ENCODE = 0; +const int32_t CBC_DataMatrixDecodedBitStreamParser::ASCII_ENCODE = 1; +const int32_t CBC_DataMatrixDecodedBitStreamParser::C40_ENCODE = 2; +const int32_t CBC_DataMatrixDecodedBitStreamParser::TEXT_ENCODE = 3; +const int32_t CBC_DataMatrixDecodedBitStreamParser::ANSIX12_ENCODE = 4; +const int32_t CBC_DataMatrixDecodedBitStreamParser::EDIFACT_ENCODE = 5; +const int32_t CBC_DataMatrixDecodedBitStreamParser::BASE256_ENCODE = 6; +CBC_DataMatrixDecodedBitStreamParser::CBC_DataMatrixDecodedBitStreamParser() {} +CBC_DataMatrixDecodedBitStreamParser::~CBC_DataMatrixDecodedBitStreamParser() {} +CBC_CommonDecoderResult* CBC_DataMatrixDecodedBitStreamParser::Decode( + CFX_ByteArray& bytes, + int32_t& e) { + CBC_CommonBitSource bits(&bytes); + CFX_ByteString result; + CFX_ByteString resultTrailer; + CFX_Int32Array byteSegments; + int32_t mode = ASCII_ENCODE; + do { + if (mode == 1) { + mode = DecodeAsciiSegment(&bits, result, resultTrailer, e); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + } else { + switch (mode) { + case 2: + DecodeC40Segment(&bits, result, e); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + break; + case 3: + DecodeTextSegment(&bits, result, e); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + break; + case 4: + DecodeAnsiX12Segment(&bits, result, e); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + break; + case 5: + DecodeEdifactSegment(&bits, result, e); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + break; + case 6: + DecodeBase256Segment(&bits, result, byteSegments, e); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + break; + default: + e = BCExceptionFormatException; + return NULL; + } + mode = ASCII_ENCODE; + } + } while (mode != PAD_ENCODE && bits.Available() > 0); + if (resultTrailer.GetLength() > 0) { + result += resultTrailer; + } + CBC_CommonDecoderResult* tempCp = new CBC_CommonDecoderResult(); + tempCp->Init(bytes, result, + (byteSegments.GetSize() <= 0) ? CFX_Int32Array() : byteSegments, + NULL, e); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + return tempCp; +} +int32_t CBC_DataMatrixDecodedBitStreamParser::DecodeAsciiSegment( + CBC_CommonBitSource* bits, + CFX_ByteString& result, + CFX_ByteString& resultTrailer, + int32_t& e) { + FX_CHAR buffer[128]; + FX_BOOL upperShift = FALSE; + do { + int32_t oneByte = bits->ReadBits(8, e); + BC_EXCEPTION_CHECK_ReturnValue(e, 0); + if (oneByte == 0) { + e = BCExceptionFormatException; + return 0; + } else if (oneByte <= 128) { + oneByte = upperShift ? oneByte + 128 : oneByte; + upperShift = FALSE; + result += ((FX_CHAR)(oneByte - 1)); + return ASCII_ENCODE; + } else if (oneByte == 129) { + return PAD_ENCODE; + } else if (oneByte <= 229) { + int32_t value = oneByte - 130; + FXSYS_itoa(value, buffer, 10); + if (value < 10) { + result += '0'; + buffer[1] = '\0'; + } else { + buffer[2] = '\0'; + } + result += buffer; + } else if (oneByte == 230) { + return C40_ENCODE; + } else if (oneByte == 231) { + return BASE256_ENCODE; + } else if (oneByte == 232 || oneByte == 233 || oneByte == 234) { + } else if (oneByte == 235) { + upperShift = TRUE; + } else if (oneByte == 236) { + result += "[)>"; + result += 0x1E; + result += "05"; + result += 0x1D; + resultTrailer.Insert(0, 0x1E); + resultTrailer.Insert(0 + 1, 0x04); + } else if (oneByte == 237) { + result += "[)>"; + result += 0x1E; + result += "06"; + result += 0x1D; + resultTrailer.Insert(0, 0x1E); + resultTrailer.Insert(0 + 1, 0x04); + } else if (oneByte == 238) { + return ANSIX12_ENCODE; + } else if (oneByte == 239) { + return TEXT_ENCODE; + } else if (oneByte == 240) { + return EDIFACT_ENCODE; + } else if (oneByte == 241) { + } else if (oneByte >= 242) { + if (oneByte == 254 && bits->Available() == 0) { + } else { + e = BCExceptionFormatException; + return 0; + } + } + } while (bits->Available() > 0); + return ASCII_ENCODE; +} +void CBC_DataMatrixDecodedBitStreamParser::DecodeC40Segment( + CBC_CommonBitSource* bits, + CFX_ByteString& result, + int32_t& e) { + FX_BOOL upperShift = FALSE; + CFX_Int32Array cValues; + cValues.SetSize(3); + do { + if (bits->Available() == 8) { + return; + } + int32_t firstByte = bits->ReadBits(8, e); + BC_EXCEPTION_CHECK_ReturnVoid(e); + if (firstByte == 254) { + return; + } + int32_t tempp = bits->ReadBits(8, e); + BC_EXCEPTION_CHECK_ReturnVoid(e); + ParseTwoBytes(firstByte, tempp, cValues); + int32_t shift = 0; + int32_t i; + for (i = 0; i < 3; i++) { + int32_t cValue = cValues[i]; + switch (shift) { + case 0: + if (cValue < 3) { + shift = cValue + 1; + } else if (cValue < 27) { + FX_CHAR c40char = C40_BASIC_SET_CHARS[cValue]; + if (upperShift) { + result += (FX_CHAR)(c40char + 128); + upperShift = FALSE; + } else { + result += c40char; + } + } else { + e = BCExceptionFormatException; + return; + } + break; + case 1: + if (upperShift) { + result += (FX_CHAR)(cValue + 128); + upperShift = FALSE; + } else { + result += cValue; + } + shift = 0; + break; + case 2: + if (cValue < 27) { + FX_CHAR c40char = C40_SHIFT2_SET_CHARS[cValue]; + if (upperShift) { + result += (FX_CHAR)(c40char + 128); + upperShift = FALSE; + } else { + result += c40char; + } + } else if (cValue == 27) { + e = BCExceptionFormatException; + return; + } else if (cValue == 30) { + upperShift = TRUE; + } else { + e = BCExceptionFormatException; + return; + } + shift = 0; + break; + case 3: + if (upperShift) { + result += (FX_CHAR)(cValue + 224); + upperShift = FALSE; + } else { + result += (FX_CHAR)(cValue + 96); + } + shift = 0; + break; + default: + break; + e = BCExceptionFormatException; + return; + } + } + } while (bits->Available() > 0); +} +void CBC_DataMatrixDecodedBitStreamParser::DecodeTextSegment( + CBC_CommonBitSource* bits, + CFX_ByteString& result, + int32_t& e) { + FX_BOOL upperShift = FALSE; + CFX_Int32Array cValues; + cValues.SetSize(3); + int32_t shift = 0; + do { + if (bits->Available() == 8) { + return; + } + int32_t firstByte = bits->ReadBits(8, e); + BC_EXCEPTION_CHECK_ReturnVoid(e); + if (firstByte == 254) { + return; + } + int32_t inTp = bits->ReadBits(8, e); + BC_EXCEPTION_CHECK_ReturnVoid(e); + ParseTwoBytes(firstByte, inTp, cValues); + for (int32_t i = 0; i < 3; i++) { + int32_t cValue = cValues[i]; + switch (shift) { + case 0: + if (cValue < 3) { + shift = cValue + 1; + } else if (cValue < 40) { + FX_CHAR textChar = TEXT_BASIC_SET_CHARS[cValue]; + if (upperShift) { + result += (FX_CHAR)(textChar + 128); + upperShift = FALSE; + } else { + result += textChar; + } + } else { + e = BCExceptionFormatException; + return; + } + break; + case 1: + if (upperShift) { + result += (FX_CHAR)(cValue + 128); + upperShift = FALSE; + } else { + result += cValue; + } + shift = 0; + break; + case 2: + if (cValue < 27) { + FX_CHAR c40char = C40_SHIFT2_SET_CHARS[cValue]; + if (upperShift) { + result += (FX_CHAR)(c40char + 128); + upperShift = FALSE; + } else { + result += c40char; + } + } else if (cValue == 27) { + e = BCExceptionFormatException; + return; + } else if (cValue == 30) { + upperShift = TRUE; + } else { + e = BCExceptionFormatException; + return; + } + shift = 0; + break; + case 3: + if (cValue < 19) { + FX_CHAR textChar = TEXT_SHIFT3_SET_CHARS[cValue]; + if (upperShift) { + result += (FX_CHAR)(textChar + 128); + upperShift = FALSE; + } else { + result += textChar; + } + shift = 0; + } else { + e = BCExceptionFormatException; + return; + } + break; + default: + break; + e = BCExceptionFormatException; + return; + } + } + } while (bits->Available() > 0); +} +void CBC_DataMatrixDecodedBitStreamParser::DecodeAnsiX12Segment( + CBC_CommonBitSource* bits, + CFX_ByteString& result, + int32_t& e) { + CFX_Int32Array cValues; + cValues.SetSize(3); + do { + if (bits->Available() == 8) { + return; + } + int32_t firstByte = bits->ReadBits(8, e); + BC_EXCEPTION_CHECK_ReturnVoid(e); + if (firstByte == 254) { + return; + } + int32_t iTemp1 = bits->ReadBits(8, e); + BC_EXCEPTION_CHECK_ReturnVoid(e); + ParseTwoBytes(firstByte, iTemp1, cValues); + int32_t i; + for (i = 0; i < 3; i++) { + int32_t cValue = cValues[i]; + if (cValue == 0) { + BC_FX_ByteString_Append(result, 1, '\r'); + } else if (cValue == 1) { + BC_FX_ByteString_Append(result, 1, '*'); + } else if (cValue == 2) { + BC_FX_ByteString_Append(result, 1, '>'); + } else if (cValue == 3) { + BC_FX_ByteString_Append(result, 1, ' '); + } else if (cValue < 14) { + BC_FX_ByteString_Append(result, 1, (FX_CHAR)(cValue + 44)); + } else if (cValue < 40) { + BC_FX_ByteString_Append(result, 1, (FX_CHAR)(cValue + 51)); + } else { + e = BCExceptionFormatException; + return; + } + } + } while (bits->Available() > 0); +} +void CBC_DataMatrixDecodedBitStreamParser::ParseTwoBytes( + int32_t firstByte, + int32_t secondByte, + CFX_Int32Array& result) { + int32_t fullBitValue = (firstByte << 8) + secondByte - 1; + int32_t temp = fullBitValue / 1600; + result[0] = temp; + fullBitValue -= temp * 1600; + temp = fullBitValue / 40; + result[1] = temp; + result[2] = fullBitValue - temp * 40; +} + +void CBC_DataMatrixDecodedBitStreamParser::DecodeEdifactSegment( + CBC_CommonBitSource* bits, + CFX_ByteString& result, + int32_t& e) { + FX_CHAR buffer[128]; + FX_BOOL unlatch = FALSE; + do { + if (bits->Available() <= 16) + return; + + for (int32_t i = 0; i < 4; i++) { + int32_t edifactValue = bits->ReadBits(6, e); + BC_EXCEPTION_CHECK_ReturnVoid(e); + if (edifactValue == 0x1F) + unlatch = TRUE; + + if (!unlatch) { + if ((edifactValue & 32) == 0) + edifactValue |= 64; + result += FXSYS_itoa(edifactValue, buffer, 10); + } + } + } while (!unlatch && bits->Available() > 0); +} + +void CBC_DataMatrixDecodedBitStreamParser::DecodeBase256Segment( + CBC_CommonBitSource* bits, + CFX_ByteString& result, + CFX_Int32Array& byteSegments, + int32_t& e) { + int32_t codewordPosition = 1 + bits->getByteOffset(); + int32_t iTmp = bits->ReadBits(8, e); + BC_EXCEPTION_CHECK_ReturnVoid(e); + int32_t d1 = Unrandomize255State(iTmp, codewordPosition++); + int32_t count; + if (d1 == 0) { + count = bits->Available() / 8; + } else if (d1 < 250) { + count = d1; + } else { + int32_t iTmp3 = bits->ReadBits(8, e); + BC_EXCEPTION_CHECK_ReturnVoid(e); + count = 250 * (d1 - 249) + Unrandomize255State(iTmp3, codewordPosition++); + } + if (count < 0) { + e = BCExceptionFormatException; + return; + } + CFX_ByteArray* bytes = new CFX_ByteArray(); + bytes->SetSize(count); + int32_t i; + for (i = 0; i < count; i++) { + if (bits->Available() < 8) { + e = BCExceptionFormatException; + delete bytes; + return; + } + int32_t iTemp5 = bits->ReadBits(8, e); + if (e != BCExceptionNO) { + delete bytes; + return; + } + bytes->SetAt(i, Unrandomize255State(iTemp5, codewordPosition++)); + } + BC_FX_ByteString_Append(result, *bytes); + delete bytes; +} +uint8_t CBC_DataMatrixDecodedBitStreamParser::Unrandomize255State( + int32_t randomizedBase256Codeword, + int32_t base256CodewordPosition) { + int32_t pseudoRandomNumber = ((149 * base256CodewordPosition) % 255) + 1; + int32_t tempVariable = randomizedBase256Codeword - pseudoRandomNumber; + return (uint8_t)(tempVariable >= 0 ? tempVariable : tempVariable + 256); +} diff --git a/xfa/fxbarcode/datamatrix/BC_DataMatrixDecodedBitStreamParser.h b/xfa/fxbarcode/datamatrix/BC_DataMatrixDecodedBitStreamParser.h new file mode 100644 index 0000000000..415e27b166 --- /dev/null +++ b/xfa/fxbarcode/datamatrix/BC_DataMatrixDecodedBitStreamParser.h @@ -0,0 +1,58 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef XFA_FXBARCODE_DATAMATRIX_BC_DATAMATRIXDECODEDBITSTREAMPARSER_H_ +#define XFA_FXBARCODE_DATAMATRIX_BC_DATAMATRIXDECODEDBITSTREAMPARSER_H_ +class CBC_CommonDecoderResult; +class CBC_CommonBitSource; +class CBC_DataMatrixDecodedBitStreamParser { + public: + CBC_DataMatrixDecodedBitStreamParser(); + virtual ~CBC_DataMatrixDecodedBitStreamParser(); + static CBC_CommonDecoderResult* Decode(CFX_ByteArray& bytes, int32_t& e); + + private: + static int32_t DecodeAsciiSegment(CBC_CommonBitSource* bits, + CFX_ByteString& result, + CFX_ByteString& resultTrailer, + int32_t& e); + static void DecodeC40Segment(CBC_CommonBitSource* bits, + CFX_ByteString& result, + int32_t& e); + static void DecodeTextSegment(CBC_CommonBitSource* bits, + CFX_ByteString& result, + int32_t& e); + static void DecodeAnsiX12Segment(CBC_CommonBitSource* bits, + CFX_ByteString& result, + int32_t& e); + static void ParseTwoBytes(int32_t firstByte, + int32_t secondByte, + CFX_Int32Array& result); + static void DecodeEdifactSegment(CBC_CommonBitSource* bits, + CFX_ByteString& result, + int32_t& e); + static void DecodeBase256Segment(CBC_CommonBitSource* bits, + CFX_ByteString& result, + CFX_Int32Array& byteSegments, + int32_t& e); + static uint8_t Unrandomize255State(int32_t randomizedBase256Codeword, + int32_t base256CodewordPosition); + + static const FX_CHAR C40_BASIC_SET_CHARS[]; + static const FX_CHAR C40_SHIFT2_SET_CHARS[]; + + static const FX_CHAR TEXT_BASIC_SET_CHARS[]; + static const FX_CHAR TEXT_SHIFT3_SET_CHARS[]; + static const int32_t PAD_ENCODE; + static const int32_t ASCII_ENCODE; + static const int32_t C40_ENCODE; + static const int32_t TEXT_ENCODE; + static const int32_t ANSIX12_ENCODE; + static const int32_t EDIFACT_ENCODE; + static const int32_t BASE256_ENCODE; +}; + +#endif // XFA_FXBARCODE_DATAMATRIX_BC_DATAMATRIXDECODEDBITSTREAMPARSER_H_ diff --git a/xfa/fxbarcode/datamatrix/BC_DataMatrixDecoder.cpp b/xfa/fxbarcode/datamatrix/BC_DataMatrixDecoder.cpp new file mode 100644 index 0000000000..3f765aa8f9 --- /dev/null +++ b/xfa/fxbarcode/datamatrix/BC_DataMatrixDecoder.cpp @@ -0,0 +1,114 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com +// Original code is licensed as follows: +/* + * Copyright 2007 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "xfa/fxbarcode/datamatrix/BC_DataMatrixDecoder.h" + +#include <memory> + +#include "xfa/fxbarcode/common/BC_CommonBitMatrix.h" +#include "xfa/fxbarcode/common/reedsolomon/BC_ReedSolomonDecoder.h" +#include "xfa/fxbarcode/common/reedsolomon/BC_ReedSolomonGF256.h" +#include "xfa/fxbarcode/datamatrix/BC_DataMatrixBitMatrixParser.h" +#include "xfa/fxbarcode/datamatrix/BC_DataMatrixDataBlock.h" +#include "xfa/fxbarcode/datamatrix/BC_DataMatrixDecodedBitStreamParser.h" +#include "xfa/fxbarcode/datamatrix/BC_DataMatrixVersion.h" + +CBC_DataMatrixDecoder::CBC_DataMatrixDecoder() { + m_rsDecoder = NULL; +} +void CBC_DataMatrixDecoder::Init() { + m_rsDecoder = + new CBC_ReedSolomonDecoder(CBC_ReedSolomonGF256::DataMatrixField); +} +CBC_DataMatrixDecoder::~CBC_DataMatrixDecoder() { + delete m_rsDecoder; +} +CBC_CommonDecoderResult* CBC_DataMatrixDecoder::Decode( + CBC_CommonBitMatrix* bits, + int32_t& e) { + CBC_DataMatrixBitMatrixParser parser; + parser.Init(bits, e); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + CBC_DataMatrixVersion* version = parser.GetVersion(); + std::unique_ptr<CFX_ByteArray> codewords(parser.ReadCodewords(e)); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + CFX_PtrArray* dataBlocks = + CBC_DataMatrixDataBlock::GetDataBlocks(codewords.get(), version, e); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + int32_t dataBlocksCount = dataBlocks->GetSize(); + int32_t totalBytes = 0; + int32_t i, j; + for (i = 0; i < dataBlocksCount; i++) { + totalBytes += + ((CBC_DataMatrixDataBlock*)(*dataBlocks)[i])->GetNumDataCodewords(); + } + CFX_ByteArray resultBytes; + resultBytes.SetSize(totalBytes); + for (j = 0; j < dataBlocksCount; j++) { + CFX_ByteArray* codewordBytes = + ((CBC_DataMatrixDataBlock*)(*dataBlocks)[j])->GetCodewords(); + int32_t numDataCodewords = + ((CBC_DataMatrixDataBlock*)(*dataBlocks)[j])->GetNumDataCodewords(); + CorrectErrors(*codewordBytes, numDataCodewords, e); + if (e != BCExceptionNO) { + for (int32_t i = 0; i < dataBlocks->GetSize(); i++) { + delete (CBC_DataMatrixDataBlock*)(*dataBlocks)[i]; + } + delete dataBlocks; + dataBlocks = NULL; + return NULL; + } + int32_t i; + for (i = 0; i < numDataCodewords; i++) { + resultBytes[i * dataBlocksCount + j] = (*codewordBytes)[i]; + } + } + for (i = 0; i < (dataBlocks->GetSize()); i++) { + delete (CBC_DataMatrixDataBlock*)(*dataBlocks)[i]; + } + delete dataBlocks; + dataBlocks = NULL; + CBC_CommonDecoderResult* resultR = + CBC_DataMatrixDecodedBitStreamParser::Decode(resultBytes, e); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + return resultR; +} +void CBC_DataMatrixDecoder::CorrectErrors(CFX_ByteArray& codewordBytes, + int32_t numDataCodewords, + int32_t& e) { + int32_t numCodewords = codewordBytes.GetSize(); + CFX_Int32Array codewordsInts; + codewordsInts.SetSize(numCodewords); + int32_t i; + for (i = 0; i < numCodewords; i++) { + codewordsInts[i] = codewordBytes[i] & 0xFF; + } + int32_t numECCodewords = codewordBytes.GetSize() - numDataCodewords; + m_rsDecoder->Decode(&codewordsInts, numECCodewords, e); + if (e != BCExceptionNO) { + e = BCExceptionChecksumException; + return; + } + for (i = 0; i < numDataCodewords; i++) { + codewordBytes[i] = (uint8_t)codewordsInts[i]; + } +} diff --git a/xfa/fxbarcode/datamatrix/BC_DataMatrixDecoder.h b/xfa/fxbarcode/datamatrix/BC_DataMatrixDecoder.h new file mode 100644 index 0000000000..2f70282d01 --- /dev/null +++ b/xfa/fxbarcode/datamatrix/BC_DataMatrixDecoder.h @@ -0,0 +1,30 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef XFA_FXBARCODE_DATAMATRIX_BC_DATAMATRIXDECODER_H_ +#define XFA_FXBARCODE_DATAMATRIX_BC_DATAMATRIXDECODER_H_ + +#include "core/include/fxcrt/fx_basic.h" + +class CBC_ReedSolomonDecoder; +class CBC_CommonDecoderResult; +class CBC_CommonBitMatrix; + +class CBC_DataMatrixDecoder { + public: + CBC_DataMatrixDecoder(); + virtual ~CBC_DataMatrixDecoder(); + CBC_CommonDecoderResult* Decode(CBC_CommonBitMatrix* bits, int32_t& e); + virtual void Init(); + + private: + void CorrectErrors(CFX_ByteArray& codewordBytes, + int32_t numDataCodewords, + int32_t& e); + CBC_ReedSolomonDecoder* m_rsDecoder; +}; + +#endif // XFA_FXBARCODE_DATAMATRIX_BC_DATAMATRIXDECODER_H_ diff --git a/xfa/fxbarcode/datamatrix/BC_DataMatrixDetector.cpp b/xfa/fxbarcode/datamatrix/BC_DataMatrixDetector.cpp new file mode 100644 index 0000000000..fd410097cc --- /dev/null +++ b/xfa/fxbarcode/datamatrix/BC_DataMatrixDetector.cpp @@ -0,0 +1,406 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com +// Original code is licensed as follows: +/* + * Copyright 2008 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "xfa/fxbarcode/datamatrix/BC_DataMatrixDetector.h" + +#include <algorithm> +#include <memory> + +#include "xfa/fxbarcode/BC_ResultPoint.h" +#include "xfa/fxbarcode/common/BC_CommonBitMatrix.h" +#include "xfa/fxbarcode/common/BC_WhiteRectangleDetector.h" +#include "xfa/fxbarcode/qrcode/BC_QRDetectorResult.h" +#include "xfa/fxbarcode/qrcode/BC_QRFinderPatternFinder.h" +#include "xfa/fxbarcode/qrcode/BC_QRGridSampler.h" +#include "xfa/fxbarcode/utils.h" + +const int32_t CBC_DataMatrixDetector::INTEGERS[5] = {0, 1, 2, 3, 4}; +CBC_DataMatrixDetector::CBC_DataMatrixDetector(CBC_CommonBitMatrix* image) + : m_image(image), m_rectangleDetector(NULL) {} +void CBC_DataMatrixDetector::Init(int32_t& e) { + m_rectangleDetector = new CBC_WhiteRectangleDetector(m_image); + m_rectangleDetector->Init(e); + BC_EXCEPTION_CHECK_ReturnVoid(e); +} +CBC_DataMatrixDetector::~CBC_DataMatrixDetector() { + delete m_rectangleDetector; +} +inline FX_BOOL ResultPointsAndTransitionsComparator(void* a, void* b) { + return ((CBC_ResultPointsAndTransitions*)b)->GetTransitions() > + ((CBC_ResultPointsAndTransitions*)a)->GetTransitions(); +} +CBC_QRDetectorResult* CBC_DataMatrixDetector::Detect(int32_t& e) { + CFX_PtrArray* cornerPoints = m_rectangleDetector->Detect(e); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + CBC_ResultPoint* pointA = (CBC_ResultPoint*)(*cornerPoints)[0]; + CBC_ResultPoint* pointB = (CBC_ResultPoint*)(*cornerPoints)[1]; + CBC_ResultPoint* pointC = (CBC_ResultPoint*)(*cornerPoints)[2]; + CBC_ResultPoint* pointD = (CBC_ResultPoint*)(*cornerPoints)[3]; + delete cornerPoints; + cornerPoints = NULL; + CFX_PtrArray transitions; + transitions.Add(TransitionsBetween(pointA, pointB)); + transitions.Add(TransitionsBetween(pointA, pointC)); + transitions.Add(TransitionsBetween(pointB, pointD)); + transitions.Add(TransitionsBetween(pointC, pointD)); + BC_FX_PtrArray_Sort(transitions, &ResultPointsAndTransitionsComparator); + delete ((CBC_ResultPointsAndTransitions*)transitions[2]); + delete ((CBC_ResultPointsAndTransitions*)transitions[3]); + CBC_ResultPointsAndTransitions* lSideOne = + (CBC_ResultPointsAndTransitions*)transitions[0]; + CBC_ResultPointsAndTransitions* lSideTwo = + (CBC_ResultPointsAndTransitions*)transitions[1]; + CFX_MapPtrTemplate<CBC_ResultPoint*, int32_t> pointCount; + Increment(pointCount, lSideOne->GetFrom()); + Increment(pointCount, lSideOne->GetTo()); + Increment(pointCount, lSideTwo->GetFrom()); + Increment(pointCount, lSideTwo->GetTo()); + delete ((CBC_ResultPointsAndTransitions*)transitions[1]); + delete ((CBC_ResultPointsAndTransitions*)transitions[0]); + transitions.RemoveAll(); + CBC_ResultPoint* maybeTopLeft = NULL; + CBC_ResultPoint* bottomLeft = NULL; + CBC_ResultPoint* maybeBottomRight = NULL; + FX_POSITION itBegin = pointCount.GetStartPosition(); + while (itBegin) { + CBC_ResultPoint* key = 0; + int32_t value = 0; + pointCount.GetNextAssoc(itBegin, key, value); + if (value == 2) { + bottomLeft = key; + } else { + if (maybeBottomRight == NULL) { + maybeBottomRight = key; + } else { + maybeTopLeft = key; + } + } + } + if (maybeTopLeft == NULL || bottomLeft == NULL || maybeBottomRight == NULL) { + delete pointA; + delete pointB; + delete pointC; + delete pointD; + e = BCExceptionNotFound; + return NULL; + } + CFX_PtrArray corners; + corners.SetSize(3); + corners[0] = maybeTopLeft; + corners[1] = bottomLeft; + corners[2] = maybeBottomRight; + OrderBestPatterns(&corners); + CBC_ResultPoint* bottomRight = (CBC_ResultPoint*)corners[0]; + bottomLeft = (CBC_ResultPoint*)corners[1]; + CBC_ResultPoint* topLeft = (CBC_ResultPoint*)corners[2]; + CBC_ResultPoint* topRight = NULL; + int32_t value; + if (!pointCount.Lookup(pointA, value)) { + topRight = pointA; + } else if (!pointCount.Lookup(pointB, value)) { + topRight = pointB; + } else if (!pointCount.Lookup(pointC, value)) { + topRight = pointC; + } else { + topRight = pointD; + } + int32_t dimensionTop = std::unique_ptr<CBC_ResultPointsAndTransitions>( + TransitionsBetween(topLeft, topRight)) + ->GetTransitions(); + int32_t dimensionRight = std::unique_ptr<CBC_ResultPointsAndTransitions>( + TransitionsBetween(bottomRight, topRight)) + ->GetTransitions(); + if ((dimensionTop & 0x01) == 1) { + dimensionTop++; + } + dimensionTop += 2; + if ((dimensionRight & 0x01) == 1) { + dimensionRight++; + } + dimensionRight += 2; + std::unique_ptr<CBC_CommonBitMatrix> bits; + std::unique_ptr<CBC_ResultPoint> correctedTopRight; + if (4 * dimensionTop >= 7 * dimensionRight || + 4 * dimensionRight >= 7 * dimensionTop) { + correctedTopRight.reset( + CorrectTopRightRectangular(bottomLeft, bottomRight, topLeft, topRight, + dimensionTop, dimensionRight)); + if (correctedTopRight.get() == NULL) { + correctedTopRight.reset(topRight); + } else { + delete topRight; + topRight = NULL; + } + dimensionTop = std::unique_ptr<CBC_ResultPointsAndTransitions>( + TransitionsBetween(topLeft, correctedTopRight.get())) + ->GetTransitions(); + dimensionRight = + std::unique_ptr<CBC_ResultPointsAndTransitions>( + TransitionsBetween(bottomRight, correctedTopRight.get())) + ->GetTransitions(); + if ((dimensionTop & 0x01) == 1) { + dimensionTop++; + } + if ((dimensionRight & 0x01) == 1) { + dimensionRight++; + } + bits.reset(SampleGrid(m_image, topLeft, bottomLeft, bottomRight, + correctedTopRight.get(), dimensionTop, dimensionRight, + e)); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + } else { + int32_t dimension = std::min(dimensionRight, dimensionTop); + correctedTopRight.reset( + CorrectTopRight(bottomLeft, bottomRight, topLeft, topRight, dimension)); + if (correctedTopRight.get() == NULL) { + correctedTopRight.reset(topRight); + } else { + delete topRight; + topRight = NULL; + } + int32_t dimensionCorrected = + std::max(std::unique_ptr<CBC_ResultPointsAndTransitions>( + TransitionsBetween(topLeft, correctedTopRight.get())) + ->GetTransitions(), + std::unique_ptr<CBC_ResultPointsAndTransitions>( + TransitionsBetween(bottomRight, correctedTopRight.get())) + ->GetTransitions()); + dimensionCorrected++; + if ((dimensionCorrected & 0x01) == 1) { + dimensionCorrected++; + } + bits.reset(SampleGrid(m_image, topLeft, bottomLeft, bottomRight, + correctedTopRight.get(), dimensionCorrected, + dimensionCorrected, e)); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + } + CFX_PtrArray* result = new CFX_PtrArray; + result->SetSize(4); + result->Add(topLeft); + result->Add(bottomLeft); + result->Add(bottomRight); + result->Add(correctedTopRight.release()); + return new CBC_QRDetectorResult(bits.release(), result); +} +CBC_ResultPoint* CBC_DataMatrixDetector::CorrectTopRightRectangular( + CBC_ResultPoint* bottomLeft, + CBC_ResultPoint* bottomRight, + CBC_ResultPoint* topLeft, + CBC_ResultPoint* topRight, + int32_t dimensionTop, + int32_t dimensionRight) { + FX_FLOAT corr = Distance(bottomLeft, bottomRight) / (FX_FLOAT)dimensionTop; + int32_t norm = Distance(topLeft, topRight); + FX_FLOAT cos = (topRight->GetX() - topLeft->GetX()) / norm; + FX_FLOAT sin = (topRight->GetY() - topLeft->GetY()) / norm; + std::unique_ptr<CBC_ResultPoint> c1(new CBC_ResultPoint( + topRight->GetX() + corr * cos, topRight->GetY() + corr * sin)); + corr = Distance(bottomLeft, topLeft) / (FX_FLOAT)dimensionRight; + norm = Distance(bottomRight, topRight); + cos = (topRight->GetX() - bottomRight->GetX()) / norm; + sin = (topRight->GetY() - bottomRight->GetY()) / norm; + std::unique_ptr<CBC_ResultPoint> c2(new CBC_ResultPoint( + topRight->GetX() + corr * cos, topRight->GetY() + corr * sin)); + if (!IsValid(c1.get())) { + if (IsValid(c2.get())) { + return c2.release(); + } + return NULL; + } else if (!IsValid(c2.get())) { + return c1.release(); + } + int32_t l1 = FXSYS_abs(dimensionTop - + std::unique_ptr<CBC_ResultPointsAndTransitions>( + TransitionsBetween(topLeft, c1.get())) + ->GetTransitions()) + + FXSYS_abs(dimensionRight - + std::unique_ptr<CBC_ResultPointsAndTransitions>( + TransitionsBetween(bottomRight, c1.get())) + ->GetTransitions()); + int32_t l2 = FXSYS_abs(dimensionTop - + std::unique_ptr<CBC_ResultPointsAndTransitions>( + TransitionsBetween(topLeft, c2.get())) + ->GetTransitions()) + + FXSYS_abs(dimensionRight - + std::unique_ptr<CBC_ResultPointsAndTransitions>( + TransitionsBetween(bottomRight, c2.get())) + ->GetTransitions()); + if (l1 <= l2) { + return c1.release(); + } + return c2.release(); +} +CBC_ResultPoint* CBC_DataMatrixDetector::CorrectTopRight( + CBC_ResultPoint* bottomLeft, + CBC_ResultPoint* bottomRight, + CBC_ResultPoint* topLeft, + CBC_ResultPoint* topRight, + int32_t dimension) { + FX_FLOAT corr = Distance(bottomLeft, bottomRight) / (FX_FLOAT)dimension; + int32_t norm = Distance(topLeft, topRight); + FX_FLOAT cos = (topRight->GetX() - topLeft->GetX()) / norm; + FX_FLOAT sin = (topRight->GetY() - topLeft->GetY()) / norm; + std::unique_ptr<CBC_ResultPoint> c1(new CBC_ResultPoint( + topRight->GetX() + corr * cos, topRight->GetY() + corr * sin)); + corr = Distance(bottomLeft, bottomRight) / (FX_FLOAT)dimension; + norm = Distance(bottomRight, topRight); + cos = (topRight->GetX() - bottomRight->GetX()) / norm; + sin = (topRight->GetY() - bottomRight->GetY()) / norm; + std::unique_ptr<CBC_ResultPoint> c2(new CBC_ResultPoint( + topRight->GetX() + corr * cos, topRight->GetY() + corr * sin)); + if (!IsValid(c1.get())) { + if (IsValid(c2.get())) { + return c2.release(); + } + return NULL; + } else if (!IsValid(c2.get())) { + return c1.release(); + } + int32_t l1 = FXSYS_abs(std::unique_ptr<CBC_ResultPointsAndTransitions>( + TransitionsBetween(topLeft, c1.get())) + ->GetTransitions() - + std::unique_ptr<CBC_ResultPointsAndTransitions>( + TransitionsBetween(bottomRight, c1.get())) + ->GetTransitions()); + int32_t l2 = FXSYS_abs(std::unique_ptr<CBC_ResultPointsAndTransitions>( + TransitionsBetween(topLeft, c2.get())) + ->GetTransitions() - + std::unique_ptr<CBC_ResultPointsAndTransitions>( + TransitionsBetween(bottomRight, c2.get())) + ->GetTransitions()); + return l1 <= l2 ? c1.release() : c2.release(); +} +FX_BOOL CBC_DataMatrixDetector::IsValid(CBC_ResultPoint* p) { + return p->GetX() >= 0 && p->GetX() < m_image->GetWidth() && p->GetY() > 0 && + p->GetY() < m_image->GetHeight(); +} +int32_t CBC_DataMatrixDetector::Round(FX_FLOAT d) { + return (int32_t)(d + 0.5f); +} +int32_t CBC_DataMatrixDetector::Distance(CBC_ResultPoint* a, + CBC_ResultPoint* b) { + return Round( + (FX_FLOAT)sqrt((a->GetX() - b->GetX()) * (a->GetX() - b->GetX()) + + (a->GetY() - b->GetY()) * (a->GetY() - b->GetY()))); +} +void CBC_DataMatrixDetector::Increment( + CFX_MapPtrTemplate<CBC_ResultPoint*, int32_t>& table, + CBC_ResultPoint* key) { + int32_t value; + if (table.Lookup(key, value)) { + table.SetAt(key, INTEGERS[value + 1]); + } else { + table.SetAt(key, INTEGERS[1]); + } +} +CBC_CommonBitMatrix* CBC_DataMatrixDetector::SampleGrid( + CBC_CommonBitMatrix* image, + CBC_ResultPoint* topLeft, + CBC_ResultPoint* bottomLeft, + CBC_ResultPoint* bottomRight, + CBC_ResultPoint* topRight, + int32_t dimensionX, + int32_t dimensionY, + int32_t& e) { + CBC_QRGridSampler& sampler = CBC_QRGridSampler::GetInstance(); + CBC_CommonBitMatrix* cbm = sampler.SampleGrid( + image, dimensionX, dimensionY, 0.5f, 0.5f, dimensionX - 0.5f, 0.5f, + dimensionX - 0.5f, dimensionY - 0.5f, 0.5f, dimensionY - 0.5f, + topLeft->GetX(), topLeft->GetY(), topRight->GetX(), topRight->GetY(), + bottomRight->GetX(), bottomRight->GetY(), bottomLeft->GetX(), + bottomLeft->GetY(), e); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + return cbm; +} +CBC_ResultPointsAndTransitions* CBC_DataMatrixDetector::TransitionsBetween( + CBC_ResultPoint* from, + CBC_ResultPoint* to) { + int32_t fromX = (int32_t)from->GetX(); + int32_t fromY = (int32_t)from->GetY(); + int32_t toX = (int32_t)to->GetX(); + int32_t toY = (int32_t)to->GetY(); + FX_BOOL steep = FXSYS_abs(toY - fromY) > FXSYS_abs(toX - fromX); + if (steep) { + int32_t temp = fromX; + fromX = fromY; + fromY = temp; + temp = toX; + toX = toY; + toY = temp; + } + int32_t dx = FXSYS_abs(toX - fromX); + int32_t dy = FXSYS_abs(toY - fromY); + int32_t error = -dx >> 1; + int32_t ystep = fromY < toY ? 1 : -1; + int32_t xstep = fromX < toX ? 1 : -1; + int32_t transitions = 0; + FX_BOOL inBlack = m_image->Get(steep ? fromY : fromX, steep ? fromX : fromY); + for (int32_t x = fromX, y = fromY; x != toX; x += xstep) { + FX_BOOL isBlack = m_image->Get(steep ? y : x, steep ? x : y); + if (isBlack != inBlack) { + transitions++; + inBlack = isBlack; + } + error += dy; + if (error > 0) { + if (y == toY) { + break; + } + y += ystep; + error -= dx; + } + } + return new CBC_ResultPointsAndTransitions(from, to, transitions); +} +void CBC_DataMatrixDetector::OrderBestPatterns(CFX_PtrArray* patterns) { + FX_FLOAT abDistance = (FX_FLOAT)Distance((CBC_ResultPoint*)(*patterns)[0], + (CBC_ResultPoint*)(*patterns)[1]); + FX_FLOAT bcDistance = (FX_FLOAT)Distance((CBC_ResultPoint*)(*patterns)[1], + (CBC_ResultPoint*)(*patterns)[2]); + FX_FLOAT acDistance = (FX_FLOAT)Distance((CBC_ResultPoint*)(*patterns)[0], + (CBC_ResultPoint*)(*patterns)[2]); + CBC_ResultPoint *topLeft, *topRight, *bottomLeft; + if (bcDistance >= abDistance && bcDistance >= acDistance) { + topLeft = (CBC_ResultPoint*)(*patterns)[0]; + topRight = (CBC_ResultPoint*)(*patterns)[1]; + bottomLeft = (CBC_ResultPoint*)(*patterns)[2]; + } else if (acDistance >= bcDistance && acDistance >= abDistance) { + topLeft = (CBC_ResultPoint*)(*patterns)[1]; + topRight = (CBC_ResultPoint*)(*patterns)[0]; + bottomLeft = (CBC_ResultPoint*)(*patterns)[2]; + } else { + topLeft = (CBC_ResultPoint*)(*patterns)[2]; + topRight = (CBC_ResultPoint*)(*patterns)[0]; + bottomLeft = (CBC_ResultPoint*)(*patterns)[1]; + } + if ((bottomLeft->GetY() - topLeft->GetY()) * + (topRight->GetX() - topLeft->GetX()) < + (bottomLeft->GetX() - topLeft->GetX()) * + (topRight->GetY() - topLeft->GetY())) { + CBC_ResultPoint* temp = topRight; + topRight = bottomLeft; + bottomLeft = temp; + } + (*patterns)[0] = bottomLeft; + (*patterns)[1] = topLeft; + (*patterns)[2] = topRight; +} diff --git a/xfa/fxbarcode/datamatrix/BC_DataMatrixDetector.h b/xfa/fxbarcode/datamatrix/BC_DataMatrixDetector.h new file mode 100644 index 0000000000..62d1699c0a --- /dev/null +++ b/xfa/fxbarcode/datamatrix/BC_DataMatrixDetector.h @@ -0,0 +1,78 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef XFA_FXBARCODE_DATAMATRIX_BC_DATAMATRIXDETECTOR_H_ +#define XFA_FXBARCODE_DATAMATRIX_BC_DATAMATRIXDETECTOR_H_ + +#include "core/include/fxcrt/fx_basic.h" + +class CBC_CommonBitMatrix; +class CBC_WhiteRectangleDetector; +class CBC_ResultPoint; +class CBC_QRDetectorResult; +class CBC_DataMatrixDetector; +class ResultPointsAndTransitions; +class CBC_ResultPointsAndTransitions { + public: + CBC_ResultPointsAndTransitions(CBC_ResultPoint* from, + CBC_ResultPoint* to, + int32_t transitions) { + m_from = from; + m_to = to; + m_transitions = transitions; + } + ~CBC_ResultPointsAndTransitions() {} + CBC_ResultPoint* GetFrom() { return m_from; } + CBC_ResultPoint* GetTo() { return m_to; } + int32_t GetTransitions() { return m_transitions; } + + private: + CBC_ResultPoint* m_from; + CBC_ResultPoint* m_to; + int32_t m_transitions; +}; +class CBC_DataMatrixDetector { + public: + CBC_DataMatrixDetector(CBC_CommonBitMatrix* image); + virtual ~CBC_DataMatrixDetector(); + CBC_QRDetectorResult* Detect(int32_t& e); + CBC_ResultPoint* CorrectTopRightRectangular(CBC_ResultPoint* bottomLeft, + CBC_ResultPoint* bottomRight, + CBC_ResultPoint* topLeft, + CBC_ResultPoint* topRight, + int32_t dimensionTop, + int32_t dimensionRight); + CBC_ResultPoint* CorrectTopRight(CBC_ResultPoint* bottomLeft, + CBC_ResultPoint* bottomRight, + CBC_ResultPoint* topLeft, + CBC_ResultPoint* topRight, + int32_t dimension); + CBC_CommonBitMatrix* SampleGrid(CBC_CommonBitMatrix* image, + CBC_ResultPoint* topLeft, + CBC_ResultPoint* bottomLeft, + CBC_ResultPoint* bottomRight, + CBC_ResultPoint* topRight, + int32_t dimensionX, + int32_t dimensionY, + int32_t& e); + CBC_ResultPointsAndTransitions* TransitionsBetween(CBC_ResultPoint* from, + CBC_ResultPoint* to); + FX_BOOL IsValid(CBC_ResultPoint* p); + int32_t Distance(CBC_ResultPoint* a, CBC_ResultPoint* b); + void Increment(CFX_MapPtrTemplate<CBC_ResultPoint*, int32_t>& table, + CBC_ResultPoint* key); + int32_t Round(FX_FLOAT d); + void OrderBestPatterns(CFX_PtrArray* patterns); + virtual void Init(int32_t& e); + + private: + static const int32_t INTEGERS[5]; + + CBC_CommonBitMatrix* m_image; + CBC_WhiteRectangleDetector* m_rectangleDetector; +}; + +#endif // XFA_FXBARCODE_DATAMATRIX_BC_DATAMATRIXDETECTOR_H_ diff --git a/xfa/fxbarcode/datamatrix/BC_DataMatrixReader.cpp b/xfa/fxbarcode/datamatrix/BC_DataMatrixReader.cpp new file mode 100644 index 0000000000..9a22d4db3a --- /dev/null +++ b/xfa/fxbarcode/datamatrix/BC_DataMatrixReader.cpp @@ -0,0 +1,65 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com +// Original code is licensed as follows: +/* + * Copyright 2007 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "xfa/fxbarcode/datamatrix/BC_DataMatrixReader.h" + +#include <memory> + +#include "xfa/fxbarcode/BC_BinaryBitmap.h" +#include "xfa/fxbarcode/BC_Reader.h" +#include "xfa/fxbarcode/common/BC_CommonDecoderResult.h" +#include "xfa/fxbarcode/datamatrix/BC_DataMatrixDecoder.h" +#include "xfa/fxbarcode/datamatrix/BC_DataMatrixDetector.h" +#include "xfa/fxbarcode/qrcode/BC_QRDetectorResult.h" +#include "xfa/fxbarcode/utils.h" + +CBC_DataMatrixReader::CBC_DataMatrixReader() { + m_decoder = NULL; +} +void CBC_DataMatrixReader::Init() { + m_decoder = new CBC_DataMatrixDecoder; + m_decoder->Init(); +} +CBC_DataMatrixReader::~CBC_DataMatrixReader() { + delete m_decoder; +} +CFX_ByteString CBC_DataMatrixReader::Decode(CBC_BinaryBitmap* image, + int32_t hints, + int32_t& e) { + CBC_CommonBitMatrix* cdr = image->GetBlackMatrix(e); + BC_EXCEPTION_CHECK_ReturnValue(e, ""); + CBC_DataMatrixDetector detector(cdr); + detector.Init(e); + BC_EXCEPTION_CHECK_ReturnValue(e, ""); + std::unique_ptr<CBC_QRDetectorResult> detectorResult(detector.Detect(e)); + BC_EXCEPTION_CHECK_ReturnValue(e, ""); + std::unique_ptr<CBC_CommonDecoderResult> decodeResult( + m_decoder->Decode(detectorResult->GetBits(), e)); + BC_EXCEPTION_CHECK_ReturnValue(e, ""); + return decodeResult->GetText(); +} +CFX_ByteString CBC_DataMatrixReader::Decode(CBC_BinaryBitmap* image, + int32_t& e) { + CFX_ByteString bs = Decode(image, 0, e); + BC_EXCEPTION_CHECK_ReturnValue(e, ""); + return bs; +} diff --git a/xfa/fxbarcode/datamatrix/BC_DataMatrixReader.h b/xfa/fxbarcode/datamatrix/BC_DataMatrixReader.h new file mode 100644 index 0000000000..21fc54eeb5 --- /dev/null +++ b/xfa/fxbarcode/datamatrix/BC_DataMatrixReader.h @@ -0,0 +1,28 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef XFA_FXBARCODE_DATAMATRIX_BC_DATAMATRIXREADER_H_ +#define XFA_FXBARCODE_DATAMATRIX_BC_DATAMATRIXREADER_H_ + +#include "xfa/fxbarcode/BC_Reader.h" + +class CBC_BinaryBitmap; +class CBC_DataMatrixDecoder; + +class CBC_DataMatrixReader : public CBC_Reader { + public: + CBC_DataMatrixReader(); + virtual ~CBC_DataMatrixReader(); + CFX_ByteString Decode(CBC_BinaryBitmap* image, int32_t& e); + CFX_ByteString Decode(CBC_BinaryBitmap* image, int hints, int32_t& e); + + virtual void Init(); + + private: + CBC_DataMatrixDecoder* m_decoder; +}; + +#endif // XFA_FXBARCODE_DATAMATRIX_BC_DATAMATRIXREADER_H_ diff --git a/xfa/fxbarcode/datamatrix/BC_DataMatrixSymbolInfo144.cpp b/xfa/fxbarcode/datamatrix/BC_DataMatrixSymbolInfo144.cpp new file mode 100644 index 0000000000..16c253f062 --- /dev/null +++ b/xfa/fxbarcode/datamatrix/BC_DataMatrixSymbolInfo144.cpp @@ -0,0 +1,40 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com +// Original code is licensed as follows: +/* + * Copyright 2006 Jeremias Maerki + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "xfa/fxbarcode/datamatrix/BC_DataMatrixSymbolInfo144.h" +#include "xfa/fxbarcode/datamatrix/BC_Encoder.h" +#include "xfa/fxbarcode/datamatrix/BC_SymbolInfo.h" +#include "xfa/fxbarcode/datamatrix/BC_SymbolShapeHint.h" + +CBC_DataMatrixSymbolInfo144::CBC_DataMatrixSymbolInfo144() + : CBC_SymbolInfo(FALSE, 1558, 620, 22, 22, 36) { + m_rsBlockData = -1; + m_rsBlockError = 62; +} +CBC_DataMatrixSymbolInfo144::~CBC_DataMatrixSymbolInfo144() {} +int32_t CBC_DataMatrixSymbolInfo144::getInterleavedBlockCount() { + return 10; +} +int32_t CBC_DataMatrixSymbolInfo144getDataLengthForInterleavedBlock( + int32_t index) { + return (index <= 8) ? 156 : 155; +} diff --git a/xfa/fxbarcode/datamatrix/BC_DataMatrixSymbolInfo144.h b/xfa/fxbarcode/datamatrix/BC_DataMatrixSymbolInfo144.h new file mode 100644 index 0000000000..4d6cdc1291 --- /dev/null +++ b/xfa/fxbarcode/datamatrix/BC_DataMatrixSymbolInfo144.h @@ -0,0 +1,20 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef XFA_FXBARCODE_DATAMATRIX_BC_DATAMATRIXSYMBOLINFO144_H_ +#define XFA_FXBARCODE_DATAMATRIX_BC_DATAMATRIXSYMBOLINFO144_H_ + +#include "xfa/fxbarcode/datamatrix/BC_SymbolInfo.h" + +class CBC_DataMatrixSymbolInfo144 : public CBC_SymbolInfo { + public: + CBC_DataMatrixSymbolInfo144(); + virtual ~CBC_DataMatrixSymbolInfo144(); + int32_t getInterleavedBlockCount(); + int32_t getDataLengthForInterleavedBlock(int32_t index); +}; + +#endif // XFA_FXBARCODE_DATAMATRIX_BC_DATAMATRIXSYMBOLINFO144_H_ diff --git a/xfa/fxbarcode/datamatrix/BC_DataMatrixVersion.cpp b/xfa/fxbarcode/datamatrix/BC_DataMatrixVersion.cpp new file mode 100644 index 0000000000..50131f3dc2 --- /dev/null +++ b/xfa/fxbarcode/datamatrix/BC_DataMatrixVersion.cpp @@ -0,0 +1,173 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com +// Original code is licensed as follows: +/* + * Copyright 2007 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <stdint.h> + +#include "xfa/fxbarcode/datamatrix/BC_DataMatrixVersion.h" +#include "xfa/fxbarcode/utils.h" + +CFX_PtrArray* CBC_DataMatrixVersion::VERSIONS = NULL; + +void CBC_DataMatrixVersion::Initialize() { + VERSIONS = new CFX_PtrArray(); +} +void CBC_DataMatrixVersion::Finalize() { + for (int32_t i = 0; i < VERSIONS->GetSize(); i++) { + delete ((CBC_DataMatrixVersion*)(VERSIONS->GetAt(i))); + } + VERSIONS->RemoveAll(); + delete VERSIONS; +} +CBC_DataMatrixVersion::CBC_DataMatrixVersion(int32_t versionNumber, + int32_t symbolSizeRows, + int32_t symbolSizeColumns, + int32_t dataRegionSizeRows, + int32_t dataRegionSizeColumns, + ECBlocks* ecBlocks) { + m_versionNumber = versionNumber; + m_symbolSizeRows = symbolSizeRows; + m_symbolSizeColumns = symbolSizeColumns; + m_dataRegionSizeRows = dataRegionSizeRows; + m_dataRegionSizeColumns = dataRegionSizeColumns; + m_ecBlocks = ecBlocks; + int32_t total = 0; + int32_t ecCodewords = ecBlocks->GetECCodewords(); + const CFX_PtrArray& ecbArray = ecBlocks->GetECBlocks(); + for (int32_t i = 0; i < ecbArray.GetSize(); i++) { + total += ((ECB*)ecbArray[i])->GetCount() * + (((ECB*)ecbArray[i])->GetDataCodewords() + ecCodewords); + } + m_totalCodewords = total; +} +CBC_DataMatrixVersion::~CBC_DataMatrixVersion() { + delete m_ecBlocks; +} +int32_t CBC_DataMatrixVersion::GetVersionNumber() { + return m_versionNumber; +} +int32_t CBC_DataMatrixVersion::GetSymbolSizeRows() { + return m_symbolSizeRows; +} +int32_t CBC_DataMatrixVersion::GetSymbolSizeColumns() { + return m_symbolSizeColumns; +} +int32_t CBC_DataMatrixVersion::GetDataRegionSizeRows() { + return m_dataRegionSizeRows; +} +int32_t CBC_DataMatrixVersion::GetDataRegionSizeColumns() { + return m_dataRegionSizeColumns; +} +int32_t CBC_DataMatrixVersion::GetTotalCodewords() { + return m_totalCodewords; +} +ECBlocks* CBC_DataMatrixVersion::GetECBlocks() { + return m_ecBlocks; +} +void CBC_DataMatrixVersion::ReleaseAll() { + for (int32_t i = 0; i < VERSIONS->GetSize(); i++) { + delete (CBC_DataMatrixVersion*)VERSIONS->GetAt(i); + } + VERSIONS->RemoveAll(); +} +CBC_DataMatrixVersion* CBC_DataMatrixVersion::GetVersionForDimensions( + int32_t numRows, + int32_t numColumns, + int32_t& e) { + if ((numRows & 0x01) != 0 || (numColumns & 0x01) != 0) { + e = BCExceptionNotFound; + return NULL; + } + if (VERSIONS->GetSize() == 0) { + VERSIONS->Add(new CBC_DataMatrixVersion(1, 10, 10, 8, 8, + new ECBlocks(5, new ECB(1, 3)))); + VERSIONS->Add(new CBC_DataMatrixVersion(2, 12, 12, 10, 10, + new ECBlocks(7, new ECB(1, 5)))); + VERSIONS->Add(new CBC_DataMatrixVersion(3, 14, 14, 12, 12, + new ECBlocks(10, new ECB(1, 8)))); + VERSIONS->Add(new CBC_DataMatrixVersion(4, 16, 16, 14, 14, + new ECBlocks(12, new ECB(1, 12)))); + VERSIONS->Add(new CBC_DataMatrixVersion(5, 18, 18, 16, 16, + new ECBlocks(14, new ECB(1, 18)))); + VERSIONS->Add(new CBC_DataMatrixVersion(6, 20, 20, 18, 18, + new ECBlocks(18, new ECB(1, 22)))); + VERSIONS->Add(new CBC_DataMatrixVersion(7, 22, 22, 20, 20, + new ECBlocks(20, new ECB(1, 30)))); + VERSIONS->Add(new CBC_DataMatrixVersion(8, 24, 24, 22, 22, + new ECBlocks(24, new ECB(1, 36)))); + VERSIONS->Add(new CBC_DataMatrixVersion(9, 26, 26, 24, 24, + new ECBlocks(28, new ECB(1, 44)))); + VERSIONS->Add(new CBC_DataMatrixVersion(10, 32, 32, 14, 14, + new ECBlocks(36, new ECB(1, 62)))); + VERSIONS->Add(new CBC_DataMatrixVersion(11, 36, 36, 16, 16, + new ECBlocks(42, new ECB(1, 86)))); + VERSIONS->Add(new CBC_DataMatrixVersion(12, 40, 40, 18, 18, + new ECBlocks(48, new ECB(1, 114)))); + VERSIONS->Add(new CBC_DataMatrixVersion(13, 44, 44, 20, 20, + new ECBlocks(56, new ECB(1, 144)))); + VERSIONS->Add(new CBC_DataMatrixVersion(14, 48, 48, 22, 22, + new ECBlocks(68, new ECB(1, 174)))); + VERSIONS->Add(new CBC_DataMatrixVersion(15, 52, 52, 24, 24, + new ECBlocks(42, new ECB(2, 102)))); + VERSIONS->Add(new CBC_DataMatrixVersion(16, 64, 64, 14, 14, + new ECBlocks(56, new ECB(2, 140)))); + VERSIONS->Add(new CBC_DataMatrixVersion(17, 72, 72, 16, 16, + new ECBlocks(36, new ECB(4, 92)))); + VERSIONS->Add(new CBC_DataMatrixVersion(18, 80, 80, 18, 18, + new ECBlocks(48, new ECB(4, 114)))); + VERSIONS->Add(new CBC_DataMatrixVersion(19, 88, 88, 20, 20, + new ECBlocks(56, new ECB(4, 144)))); + VERSIONS->Add(new CBC_DataMatrixVersion(20, 96, 96, 22, 22, + new ECBlocks(68, new ECB(4, 174)))); + VERSIONS->Add(new CBC_DataMatrixVersion(21, 104, 104, 24, 24, + new ECBlocks(56, new ECB(6, 136)))); + VERSIONS->Add(new CBC_DataMatrixVersion(22, 120, 120, 18, 18, + new ECBlocks(68, new ECB(6, 175)))); + VERSIONS->Add(new CBC_DataMatrixVersion(23, 132, 132, 20, 20, + new ECBlocks(62, new ECB(8, 163)))); + VERSIONS->Add(new CBC_DataMatrixVersion( + 24, 144, 144, 22, 22, + new ECBlocks(62, new ECB(8, 156), new ECB(2, 155)))); + VERSIONS->Add(new CBC_DataMatrixVersion(25, 8, 18, 6, 16, + new ECBlocks(7, new ECB(1, 5)))); + VERSIONS->Add(new CBC_DataMatrixVersion(26, 8, 32, 6, 14, + new ECBlocks(11, new ECB(1, 10)))); + VERSIONS->Add(new CBC_DataMatrixVersion(27, 12, 26, 10, 24, + new ECBlocks(14, new ECB(1, 16)))); + VERSIONS->Add(new CBC_DataMatrixVersion(28, 12, 36, 10, 16, + new ECBlocks(18, new ECB(1, 22)))); + VERSIONS->Add(new CBC_DataMatrixVersion(29, 16, 36, 14, 16, + new ECBlocks(24, new ECB(1, 32)))); + VERSIONS->Add(new CBC_DataMatrixVersion(30, 16, 48, 14, 22, + new ECBlocks(28, new ECB(1, 49)))); + } + int32_t numVersions = VERSIONS->GetSize(); + for (int32_t i = 0; i < numVersions; ++i) { + if (((CBC_DataMatrixVersion*)((*VERSIONS)[i]))->m_symbolSizeRows == + numRows && + ((CBC_DataMatrixVersion*)((*VERSIONS)[i]))->m_symbolSizeColumns == + numColumns) { + return (CBC_DataMatrixVersion*)(*VERSIONS)[i]; + } + } + e = BCExceptionNotFound; + return NULL; +} diff --git a/xfa/fxbarcode/datamatrix/BC_DataMatrixVersion.h b/xfa/fxbarcode/datamatrix/BC_DataMatrixVersion.h new file mode 100644 index 0000000000..8a79355153 --- /dev/null +++ b/xfa/fxbarcode/datamatrix/BC_DataMatrixVersion.h @@ -0,0 +1,92 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef XFA_FXBARCODE_DATAMATRIX_BC_DATAMATRIXVERSION_H_ +#define XFA_FXBARCODE_DATAMATRIX_BC_DATAMATRIXVERSION_H_ + +#include "core/include/fxcrt/fx_basic.h" + +class CBC_DataMatrixVersion; + +class ECB { + public: + ECB(int32_t count, int32_t dataCodewords) { + m_count = count; + m_dataCodewords = dataCodewords; + } + + int32_t GetCount() { return m_count; } + + int32_t GetDataCodewords() { return m_dataCodewords; } + + private: + int32_t m_count; + int32_t m_dataCodewords; +}; + +class ECBlocks { + public: + ECBlocks(int32_t ecCodewords, ECB* ecBlocks) { + m_ecCodewords = ecCodewords; + m_ecBlocks.Add(ecBlocks); + } + + ECBlocks(int32_t ecCodewords, ECB* ecBlocks1, ECB* ecBlocks2) { + m_ecCodewords = ecCodewords; + m_ecBlocks.Add(ecBlocks1); + m_ecBlocks.Add(ecBlocks2); + } + ~ECBlocks() { + for (int32_t i = 0; i < m_ecBlocks.GetSize(); i++) { + delete (ECB*)m_ecBlocks[i]; + } + m_ecBlocks.RemoveAll(); + } + + int32_t GetECCodewords() { return m_ecCodewords; } + + const CFX_PtrArray& GetECBlocks() { return m_ecBlocks; } + + private: + int32_t m_ecCodewords; + CFX_PtrArray m_ecBlocks; +}; + +class CBC_DataMatrixVersion { + public: + CBC_DataMatrixVersion(int32_t versionNumber, + int32_t symbolSizeRows, + int32_t symbolSizeColumns, + int32_t dataRegionSizeRows, + int32_t dataRegionSizeColumns, + ECBlocks* ecBlocks); + virtual ~CBC_DataMatrixVersion(); + static void Initialize(); + static void Finalize(); + int32_t GetVersionNumber(); + int32_t GetSymbolSizeRows(); + int32_t GetSymbolSizeColumns(); + int32_t GetDataRegionSizeRows(); + int32_t GetDataRegionSizeColumns(); + int32_t GetTotalCodewords(); + ECBlocks* GetECBlocks(); + static CBC_DataMatrixVersion* GetVersionForDimensions(int32_t numRows, + int32_t numColumns, + int32_t& e); + static void ReleaseAll(); + + private: + int32_t m_versionNumber; + int32_t m_symbolSizeRows; + int32_t m_symbolSizeColumns; + int32_t m_dataRegionSizeRows; + int32_t m_dataRegionSizeColumns; + ECBlocks* m_ecBlocks; + int32_t m_totalCodewords; + static CFX_PtrArray* VERSIONS; +}; + +#endif // XFA_FXBARCODE_DATAMATRIX_BC_DATAMATRIXVERSION_H_ diff --git a/xfa/fxbarcode/datamatrix/BC_DataMatrixWriter.cpp b/xfa/fxbarcode/datamatrix/BC_DataMatrixWriter.cpp new file mode 100644 index 0000000000..03cd5fba50 --- /dev/null +++ b/xfa/fxbarcode/datamatrix/BC_DataMatrixWriter.cpp @@ -0,0 +1,136 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com +// Original code is licensed as follows: +/* + * Copyright 2008 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "xfa/fxbarcode/BC_BinaryBitmap.h" +#include "xfa/fxbarcode/BC_Dimension.h" +#include "xfa/fxbarcode/BC_TwoDimWriter.h" +#include "xfa/fxbarcode/BC_UtilCodingConvert.h" +#include "xfa/fxbarcode/BC_Writer.h" +#include "xfa/fxbarcode/common/BC_CommonBitMatrix.h" +#include "xfa/fxbarcode/common/BC_CommonByteMatrix.h" +#include "xfa/fxbarcode/datamatrix/BC_ASCIIEncoder.h" +#include "xfa/fxbarcode/datamatrix/BC_Base256Encoder.h" +#include "xfa/fxbarcode/datamatrix/BC_C40Encoder.h" +#include "xfa/fxbarcode/datamatrix/BC_DataMatrixSymbolInfo144.h" +#include "xfa/fxbarcode/datamatrix/BC_DataMatrixWriter.h" +#include "xfa/fxbarcode/datamatrix/BC_DefaultPlacement.h" +#include "xfa/fxbarcode/datamatrix/BC_EdifactEncoder.h" +#include "xfa/fxbarcode/datamatrix/BC_Encoder.h" +#include "xfa/fxbarcode/datamatrix/BC_EncoderContext.h" +#include "xfa/fxbarcode/datamatrix/BC_ErrorCorrection.h" +#include "xfa/fxbarcode/datamatrix/BC_HighLevelEncoder.h" +#include "xfa/fxbarcode/datamatrix/BC_SymbolInfo.h" +#include "xfa/fxbarcode/datamatrix/BC_SymbolShapeHint.h" +#include "xfa/fxbarcode/datamatrix/BC_TextEncoder.h" +#include "xfa/fxbarcode/datamatrix/BC_X12Encoder.h" + +CBC_DataMatrixWriter::CBC_DataMatrixWriter() {} +CBC_DataMatrixWriter::~CBC_DataMatrixWriter() {} +FX_BOOL CBC_DataMatrixWriter::SetErrorCorrectionLevel(int32_t level) { + m_iCorrectLevel = level; + return TRUE; +} +uint8_t* CBC_DataMatrixWriter::Encode(const CFX_WideString& contents, + int32_t& outWidth, + int32_t& outHeight, + int32_t& e) { + if (outWidth < 0 || outHeight < 0) { + e = BCExceptionHeightAndWidthMustBeAtLeast1; + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + } + CBC_SymbolShapeHint::SymbolShapeHint shape = + CBC_SymbolShapeHint::FORCE_SQUARE; + CBC_Dimension* minSize = NULL; + CBC_Dimension* maxSize = NULL; + CFX_WideString ecLevel; + CFX_WideString encoded = CBC_HighLevelEncoder::encodeHighLevel( + contents, ecLevel, shape, minSize, maxSize, e); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + CBC_SymbolInfo* symbolInfo = CBC_SymbolInfo::lookup( + encoded.GetLength(), shape, minSize, maxSize, TRUE, e); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + CFX_WideString codewords = + CBC_ErrorCorrection::encodeECC200(encoded, symbolInfo, e); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + CBC_DefaultPlacement* placement = + new CBC_DefaultPlacement(codewords, symbolInfo->getSymbolDataWidth(e), + symbolInfo->getSymbolDataHeight(e)); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + placement->place(); + CBC_CommonByteMatrix* bytematrix = encodeLowLevel(placement, symbolInfo, e); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + outWidth = bytematrix->GetWidth(); + outHeight = bytematrix->GetHeight(); + uint8_t* result = FX_Alloc2D(uint8_t, outWidth, outHeight); + FXSYS_memcpy(result, bytematrix->GetArray(), outWidth * outHeight); + delete bytematrix; + delete placement; + return result; +} +CBC_CommonByteMatrix* CBC_DataMatrixWriter::encodeLowLevel( + CBC_DefaultPlacement* placement, + CBC_SymbolInfo* symbolInfo, + int32_t& e) { + int32_t symbolWidth = symbolInfo->getSymbolDataWidth(e); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + int32_t symbolHeight = symbolInfo->getSymbolDataHeight(e); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + CBC_CommonByteMatrix* matrix = new CBC_CommonByteMatrix( + symbolInfo->getSymbolWidth(e), symbolInfo->getSymbolHeight(e)); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + matrix->Init(); + int32_t matrixY = 0; + for (int32_t y = 0; y < symbolHeight; y++) { + int32_t matrixX; + if ((y % symbolInfo->m_matrixHeight) == 0) { + matrixX = 0; + for (int32_t x = 0; x < symbolInfo->getSymbolWidth(e); x++) { + matrix->Set(matrixX, matrixY, (x % 2) == 0); + matrixX++; + } + matrixY++; + } + matrixX = 0; + for (int32_t x = 0; x < symbolWidth; x++) { + if ((x % symbolInfo->m_matrixWidth) == 0) { + matrix->Set(matrixX, matrixY, TRUE); + matrixX++; + } + matrix->Set(matrixX, matrixY, placement->getBit(x, y)); + matrixX++; + if ((x % symbolInfo->m_matrixWidth) == symbolInfo->m_matrixWidth - 1) { + matrix->Set(matrixX, matrixY, (y % 2) == 0); + matrixX++; + } + } + matrixY++; + if ((y % symbolInfo->m_matrixHeight) == symbolInfo->m_matrixHeight - 1) { + matrixX = 0; + for (int32_t x = 0; x < symbolInfo->getSymbolWidth(e); x++) { + matrix->Set(matrixX, matrixY, TRUE); + matrixX++; + } + matrixY++; + } + } + return matrix; +} diff --git a/xfa/fxbarcode/datamatrix/BC_DataMatrixWriter.h b/xfa/fxbarcode/datamatrix/BC_DataMatrixWriter.h new file mode 100644 index 0000000000..7c19a07c19 --- /dev/null +++ b/xfa/fxbarcode/datamatrix/BC_DataMatrixWriter.h @@ -0,0 +1,33 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef XFA_FXBARCODE_DATAMATRIX_BC_DATAMATRIXWRITER_H_ +#define XFA_FXBARCODE_DATAMATRIX_BC_DATAMATRIXWRITER_H_ + +#include "xfa/fxbarcode/BC_TwoDimWriter.h" + +class CBC_CommonByteMatrix; +class CBC_DefaultPlacement; +class CBC_SymbolInfo; + +class CBC_DataMatrixWriter : public CBC_TwoDimWriter { + public: + CBC_DataMatrixWriter(); + virtual ~CBC_DataMatrixWriter(); + uint8_t* Encode(const CFX_WideString& contents, + int32_t& outWidth, + int32_t& outHeight, + int32_t& e); + FX_BOOL SetErrorCorrectionLevel(int32_t level); + + private: + static CBC_CommonByteMatrix* encodeLowLevel(CBC_DefaultPlacement* placement, + CBC_SymbolInfo* symbolInfo, + int32_t& e); + int32_t m_iCorrectLevel; +}; + +#endif // XFA_FXBARCODE_DATAMATRIX_BC_DATAMATRIXWRITER_H_ diff --git a/xfa/fxbarcode/datamatrix/BC_DefaultPlacement.cpp b/xfa/fxbarcode/datamatrix/BC_DefaultPlacement.cpp new file mode 100644 index 0000000000..830df224ca --- /dev/null +++ b/xfa/fxbarcode/datamatrix/BC_DefaultPlacement.cpp @@ -0,0 +1,164 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com +// Original code is licensed as follows: +/* + * Copyright 2006 Jeremias Maerki. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "xfa/fxbarcode/datamatrix/BC_DefaultPlacement.h" +#include "xfa/fxbarcode/datamatrix/BC_Encoder.h" + +CBC_DefaultPlacement::CBC_DefaultPlacement(CFX_WideString codewords, + int32_t numcols, + int32_t numrows) { + m_codewords = codewords; + m_numcols = numcols; + m_numrows = numrows; + m_bits.SetSize(numcols * numrows); + for (int32_t i = 0; i < numcols * numrows; i++) { + m_bits[i] = (uint8_t)2; + } +} +CBC_DefaultPlacement::~CBC_DefaultPlacement() { + m_bits.RemoveAll(); +} +int32_t CBC_DefaultPlacement::getNumrows() { + return m_numrows; +} +int32_t CBC_DefaultPlacement::getNumcols() { + return m_numcols; +} +CFX_ByteArray& CBC_DefaultPlacement::getBits() { + return m_bits; +} +FX_BOOL CBC_DefaultPlacement::getBit(int32_t col, int32_t row) { + return m_bits[row * m_numcols + col] == 1; +} +void CBC_DefaultPlacement::setBit(int32_t col, int32_t row, FX_BOOL bit) { + m_bits[row * m_numcols + col] = bit ? (uint8_t)1 : (uint8_t)0; +} +FX_BOOL CBC_DefaultPlacement::hasBit(int32_t col, int32_t row) { + return m_bits[row * m_numcols + col] != 2; +} +void CBC_DefaultPlacement::place() { + int32_t pos = 0; + int32_t row = 4; + int32_t col = 0; + do { + if ((row == m_numrows) && (col == 0)) { + corner1(pos++); + } + if ((row == m_numrows - 2) && (col == 0) && ((m_numcols % 4) != 0)) { + corner2(pos++); + } + if ((row == m_numrows - 2) && (col == 0) && (m_numcols % 8 == 4)) { + corner3(pos++); + } + if ((row == m_numrows + 4) && (col == 2) && ((m_numcols % 8) == 0)) { + corner4(pos++); + } + do { + if ((row < m_numrows) && (col >= 0) && !hasBit(col, row)) { + utah(row, col, pos++); + } + row -= 2; + col += 2; + } while (row >= 0 && (col < m_numcols)); + row++; + col += 3; + do { + if ((row >= 0) && (col < m_numcols) && !hasBit(col, row)) { + utah(row, col, pos++); + } + row += 2; + col -= 2; + } while ((row < m_numrows) && (col >= 0)); + row += 3; + col++; + } while ((row < m_numrows) || (col < m_numcols)); + if (!hasBit(m_numcols - 1, m_numrows - 1)) { + setBit(m_numcols - 1, m_numrows - 1, TRUE); + setBit(m_numcols - 2, m_numrows - 2, TRUE); + } +} +void CBC_DefaultPlacement::module(int32_t row, + int32_t col, + int32_t pos, + int32_t bit) { + if (row < 0) { + row += m_numrows; + col += 4 - ((m_numrows + 4) % 8); + } + if (col < 0) { + col += m_numcols; + row += 4 - ((m_numcols + 4) % 8); + } + int32_t v = m_codewords.GetAt(pos); + v &= 1 << (8 - bit); + setBit(col, row, v != 0); +} +void CBC_DefaultPlacement::utah(int32_t row, int32_t col, int32_t pos) { + module(row - 2, col - 2, pos, 1); + module(row - 2, col - 1, pos, 2); + module(row - 1, col - 2, pos, 3); + module(row - 1, col - 1, pos, 4); + module(row - 1, col, pos, 5); + module(row, col - 2, pos, 6); + module(row, col - 1, pos, 7); + module(row, col, pos, 8); +} +void CBC_DefaultPlacement::corner1(int32_t pos) { + module(m_numrows - 1, 0, pos, 1); + module(m_numrows - 1, 1, pos, 2); + module(m_numrows - 1, 2, pos, 3); + module(0, m_numcols - 2, pos, 4); + module(0, m_numcols - 1, pos, 5); + module(1, m_numcols - 1, pos, 6); + module(2, m_numcols - 1, pos, 7); + module(3, m_numcols - 1, pos, 8); +} +void CBC_DefaultPlacement::corner2(int32_t pos) { + module(m_numrows - 3, 0, pos, 1); + module(m_numrows - 2, 0, pos, 2); + module(m_numrows - 1, 0, pos, 3); + module(0, m_numcols - 4, pos, 4); + module(0, m_numcols - 3, pos, 5); + module(0, m_numcols - 2, pos, 6); + module(0, m_numcols - 1, pos, 7); + module(1, m_numcols - 1, pos, 8); +} +void CBC_DefaultPlacement::corner3(int32_t pos) { + module(m_numrows - 3, 0, pos, 1); + module(m_numrows - 2, 0, pos, 2); + module(m_numrows - 1, 0, pos, 3); + module(0, m_numcols - 2, pos, 4); + module(0, m_numcols - 1, pos, 5); + module(1, m_numcols - 1, pos, 6); + module(2, m_numcols - 1, pos, 7); + module(3, m_numcols - 1, pos, 8); +} +void CBC_DefaultPlacement::corner4(int32_t pos) { + module(m_numrows - 1, 0, pos, 1); + module(m_numrows - 1, m_numcols - 1, pos, 2); + module(0, m_numcols - 3, pos, 3); + module(0, m_numcols - 2, pos, 4); + module(0, m_numcols - 1, pos, 5); + module(1, m_numcols - 3, pos, 6); + module(1, m_numcols - 2, pos, 7); + module(1, m_numcols - 1, pos, 8); +} diff --git a/xfa/fxbarcode/datamatrix/BC_DefaultPlacement.h b/xfa/fxbarcode/datamatrix/BC_DefaultPlacement.h new file mode 100644 index 0000000000..49008f3356 --- /dev/null +++ b/xfa/fxbarcode/datamatrix/BC_DefaultPlacement.h @@ -0,0 +1,40 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef XFA_FXBARCODE_DATAMATRIX_BC_DEFAULTPLACEMENT_H_ +#define XFA_FXBARCODE_DATAMATRIX_BC_DEFAULTPLACEMENT_H_ + +#include "core/include/fxcrt/fx_basic.h" + +class CBC_DefaultPlacement { + public: + CBC_DefaultPlacement(CFX_WideString codewords, + int32_t numcols, + int32_t numrows); + virtual ~CBC_DefaultPlacement(); + + int32_t getNumrows(); + int32_t getNumcols(); + CFX_ByteArray& getBits(); + FX_BOOL getBit(int32_t col, int32_t row); + void setBit(int32_t col, int32_t row, FX_BOOL bit); + FX_BOOL hasBit(int32_t col, int32_t row); + void place(); + + private: + CFX_WideString m_codewords; + int32_t m_numrows; + int32_t m_numcols; + CFX_ByteArray m_bits; + void module(int32_t row, int32_t col, int32_t pos, int32_t bit); + void utah(int32_t row, int32_t col, int32_t pos); + void corner1(int32_t pos); + void corner2(int32_t pos); + void corner3(int32_t pos); + void corner4(int32_t pos); +}; + +#endif // XFA_FXBARCODE_DATAMATRIX_BC_DEFAULTPLACEMENT_H_ diff --git a/xfa/fxbarcode/datamatrix/BC_EdifactEncoder.cpp b/xfa/fxbarcode/datamatrix/BC_EdifactEncoder.cpp new file mode 100644 index 0000000000..d1f5b9796d --- /dev/null +++ b/xfa/fxbarcode/datamatrix/BC_EdifactEncoder.cpp @@ -0,0 +1,154 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com +// Original code is licensed as follows: +/* + * Copyright 2006-2007 Jeremias Maerki. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "xfa/fxbarcode/BC_Dimension.h" +#include "xfa/fxbarcode/common/BC_CommonBitMatrix.h" +#include "xfa/fxbarcode/datamatrix/BC_EdifactEncoder.h" +#include "xfa/fxbarcode/datamatrix/BC_Encoder.h" +#include "xfa/fxbarcode/datamatrix/BC_EncoderContext.h" +#include "xfa/fxbarcode/datamatrix/BC_HighLevelEncoder.h" +#include "xfa/fxbarcode/datamatrix/BC_SymbolInfo.h" +#include "xfa/fxbarcode/datamatrix/BC_SymbolShapeHint.h" + +CBC_EdifactEncoder::CBC_EdifactEncoder() {} +CBC_EdifactEncoder::~CBC_EdifactEncoder() {} +int32_t CBC_EdifactEncoder::getEncodingMode() { + return EDIFACT_ENCODATION; +} +void CBC_EdifactEncoder::Encode(CBC_EncoderContext& context, int32_t& e) { + CFX_WideString buffer; + while (context.hasMoreCharacters()) { + FX_WCHAR c = context.getCurrentChar(); + encodeChar(c, buffer, e); + if (e != BCExceptionNO) { + return; + } + context.m_pos++; + int32_t count = buffer.GetLength(); + if (count >= 4) { + context.writeCodewords(encodeToCodewords(buffer, 0, e)); + if (e != BCExceptionNO) { + return; + } + buffer.Delete(0, 4); + int32_t newMode = CBC_HighLevelEncoder::lookAheadTest( + context.m_msg, context.m_pos, getEncodingMode()); + if (newMode != getEncodingMode()) { + context.signalEncoderChange(ASCII_ENCODATION); + break; + } + } + } + buffer += (FX_WCHAR)31; + handleEOD(context, buffer, e); +} +void CBC_EdifactEncoder::handleEOD(CBC_EncoderContext& context, + CFX_WideString buffer, + int32_t& e) { + int32_t count = buffer.GetLength(); + if (count == 0) { + return; + } + if (count == 1) { + context.updateSymbolInfo(e); + if (e != BCExceptionNO) { + return; + } + int32_t available = + context.m_symbolInfo->m_dataCapacity - context.getCodewordCount(); + int32_t remaining = context.getRemainingCharacters(); + if (remaining == 0 && available <= 2) { + return; + } + } + if (count > 4) { + e = BCExceptionIllegalStateCountMustNotExceed4; + return; + } + int32_t restChars = count - 1; + CFX_WideString encoded = encodeToCodewords(buffer, 0, e); + if (e != BCExceptionNO) { + return; + } + FX_BOOL endOfSymbolReached = !context.hasMoreCharacters(); + FX_BOOL restInAscii = endOfSymbolReached && restChars <= 2; + if (restChars <= 2) { + context.updateSymbolInfo(context.getCodewordCount() + restChars, e); + if (e != BCExceptionNO) { + return; + } + int32_t available = + context.m_symbolInfo->m_dataCapacity - context.getCodewordCount(); + if (available >= 3) { + restInAscii = FALSE; + context.updateSymbolInfo(context.getCodewordCount() + encoded.GetLength(), + e); + if (e != BCExceptionNO) { + return; + } + } + } + if (restInAscii) { + context.resetSymbolInfo(); + context.m_pos -= restChars; + } else { + context.writeCodewords(encoded); + } + context.signalEncoderChange(ASCII_ENCODATION); +} +void CBC_EdifactEncoder::encodeChar(FX_WCHAR c, + CFX_WideString& sb, + int32_t& e) { + if (c >= ' ' && c <= '?') { + sb += c; + } else if (c >= '@' && c <= '^') { + sb += (FX_WCHAR)(c - 64); + } else { + CBC_HighLevelEncoder::illegalCharacter(c, e); + } +} +CFX_WideString CBC_EdifactEncoder::encodeToCodewords(CFX_WideString sb, + int32_t startPos, + int32_t& e) { + int32_t len = sb.GetLength() - startPos; + if (len == 0) { + e = BCExceptionNoContents; + return (FX_WCHAR*)""; + } + FX_WCHAR c1 = sb.GetAt(startPos); + FX_WCHAR c2 = len >= 2 ? sb.GetAt(startPos + 1) : 0; + FX_WCHAR c3 = len >= 3 ? sb.GetAt(startPos + 2) : 0; + FX_WCHAR c4 = len >= 4 ? sb.GetAt(startPos + 3) : 0; + int32_t v = (c1 << 18) + (c2 << 12) + (c3 << 6) + c4; + FX_WCHAR cw1 = (FX_WCHAR)((v >> 16) & 255); + FX_WCHAR cw2 = (FX_WCHAR)((v >> 8) & 255); + FX_WCHAR cw3 = (FX_WCHAR)(v & 255); + CFX_WideString res; + res += cw1; + if (len >= 2) { + res += cw2; + } + if (len >= 3) { + res += cw3; + } + return res; +} diff --git a/xfa/fxbarcode/datamatrix/BC_EdifactEncoder.h b/xfa/fxbarcode/datamatrix/BC_EdifactEncoder.h new file mode 100644 index 0000000000..fd37ffb5b4 --- /dev/null +++ b/xfa/fxbarcode/datamatrix/BC_EdifactEncoder.h @@ -0,0 +1,29 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef XFA_FXBARCODE_DATAMATRIX_BC_EDIFACTENCODER_H_ +#define XFA_FXBARCODE_DATAMATRIX_BC_EDIFACTENCODER_H_ + +#include "xfa/fxbarcode/datamatrix/BC_Encoder.h" + +class CBC_EdifactEncoder : public CBC_Encoder { + public: + CBC_EdifactEncoder(); + virtual ~CBC_EdifactEncoder(); + int32_t getEncodingMode(); + void Encode(CBC_EncoderContext& context, int32_t& e); + + private: + static void handleEOD(CBC_EncoderContext& context, + CFX_WideString buffer, + int32_t& e); + static void encodeChar(FX_WCHAR c, CFX_WideString& sb, int32_t& e); + static CFX_WideString encodeToCodewords(CFX_WideString sb, + int32_t startPos, + int32_t& e); +}; + +#endif // XFA_FXBARCODE_DATAMATRIX_BC_EDIFACTENCODER_H_ diff --git a/xfa/fxbarcode/datamatrix/BC_Encoder.cpp b/xfa/fxbarcode/datamatrix/BC_Encoder.cpp new file mode 100644 index 0000000000..bf815bdfa7 --- /dev/null +++ b/xfa/fxbarcode/datamatrix/BC_Encoder.cpp @@ -0,0 +1,10 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#include "xfa/fxbarcode/datamatrix/BC_Encoder.h" + +CBC_Encoder::CBC_Encoder() {} +CBC_Encoder::~CBC_Encoder() {} diff --git a/xfa/fxbarcode/datamatrix/BC_Encoder.h b/xfa/fxbarcode/datamatrix/BC_Encoder.h new file mode 100644 index 0000000000..78dc6ac447 --- /dev/null +++ b/xfa/fxbarcode/datamatrix/BC_Encoder.h @@ -0,0 +1,21 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef XFA_FXBARCODE_DATAMATRIX_BC_ENCODER_H_ +#define XFA_FXBARCODE_DATAMATRIX_BC_ENCODER_H_ + +#include "xfa/fxbarcode/utils.h" + +class CBC_EncoderContext; +class CBC_Encoder { + public: + CBC_Encoder(); + virtual ~CBC_Encoder(); + virtual int32_t getEncodingMode() = 0; + virtual void Encode(CBC_EncoderContext& context, int32_t& e) = 0; +}; + +#endif // XFA_FXBARCODE_DATAMATRIX_BC_ENCODER_H_ diff --git a/xfa/fxbarcode/datamatrix/BC_EncoderContext.cpp b/xfa/fxbarcode/datamatrix/BC_EncoderContext.cpp new file mode 100644 index 0000000000..c99dcb7d7a --- /dev/null +++ b/xfa/fxbarcode/datamatrix/BC_EncoderContext.cpp @@ -0,0 +1,111 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com +// Original code is licensed as follows: +/* + * Copyright 2006-2007 Jeremias Maerki. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "xfa/fxbarcode/BC_Dimension.h" +#include "xfa/fxbarcode/BC_UtilCodingConvert.h" +#include "xfa/fxbarcode/common/BC_CommonBitMatrix.h" +#include "xfa/fxbarcode/datamatrix/BC_Encoder.h" +#include "xfa/fxbarcode/datamatrix/BC_EncoderContext.h" +#include "xfa/fxbarcode/datamatrix/BC_SymbolInfo.h" +#include "xfa/fxbarcode/datamatrix/BC_SymbolShapeHint.h" + +CBC_EncoderContext::CBC_EncoderContext(const CFX_WideString msg, + CFX_WideString ecLevel, + int32_t& e) { + CFX_ByteString dststr; + CBC_UtilCodingConvert::UnicodeToUTF8(msg, dststr); + CFX_WideString sb; + int32_t c = dststr.GetLength(); + for (int32_t i = 0; i < c; i++) { + FX_WCHAR ch = (FX_WCHAR)(dststr.GetAt(i) & 0xff); + if (ch == '?' && dststr.GetAt(i) != '?') { + e = BCExceptionCharactersOutsideISO88591Encoding; + } + sb += ch; + } + m_msg = sb; + m_shape = FORCE_NONE; + m_newEncoding = -1; + m_pos = 0; + m_symbolInfo = NULL; + m_skipAtEnd = 0; + m_maxSize = NULL; + m_minSize = NULL; +} +CBC_EncoderContext::~CBC_EncoderContext() {} +void CBC_EncoderContext::setSymbolShape(SymbolShapeHint shape) { + m_shape = shape; +} +void CBC_EncoderContext::setSizeConstraints(CBC_Dimension* minSize, + CBC_Dimension* maxSize) { + m_maxSize = maxSize; + m_minSize = minSize; +} +CFX_WideString CBC_EncoderContext::getMessage() { + return m_msg; +} +void CBC_EncoderContext::setSkipAtEnd(int32_t count) { + m_skipAtEnd = count; +} +FX_WCHAR CBC_EncoderContext::getCurrentChar() { + return m_msg.GetAt(m_pos); +} +FX_WCHAR CBC_EncoderContext::getCurrent() { + return m_msg.GetAt(m_pos); +} +void CBC_EncoderContext::writeCodewords(CFX_WideString codewords) { + m_codewords += codewords; +} +void CBC_EncoderContext::writeCodeword(FX_WCHAR codeword) { + m_codewords += codeword; +} +int32_t CBC_EncoderContext::getCodewordCount() { + return m_codewords.GetLength(); +} +void CBC_EncoderContext::signalEncoderChange(int32_t encoding) { + m_newEncoding = encoding; +} +void CBC_EncoderContext::resetEncoderSignal() { + m_newEncoding = -1; +} +FX_BOOL CBC_EncoderContext::hasMoreCharacters() { + return m_pos < getTotalMessageCharCount(); +} +int32_t CBC_EncoderContext::getRemainingCharacters() { + return getTotalMessageCharCount() - m_pos; +} +void CBC_EncoderContext::updateSymbolInfo(int32_t& e) { + updateSymbolInfo(getCodewordCount(), e); +} +void CBC_EncoderContext::updateSymbolInfo(int32_t len, int32_t& e) { + if (m_symbolInfo == NULL || len > m_symbolInfo->m_dataCapacity) { + m_symbolInfo = + CBC_SymbolInfo::lookup(len, m_shape, m_minSize, m_maxSize, true, e); + BC_EXCEPTION_CHECK_ReturnVoid(e); + } +} +void CBC_EncoderContext::resetSymbolInfo() { + m_shape = FORCE_NONE; +} +int32_t CBC_EncoderContext::getTotalMessageCharCount() { + return m_msg.GetLength() - m_skipAtEnd; +} diff --git a/xfa/fxbarcode/datamatrix/BC_EncoderContext.h b/xfa/fxbarcode/datamatrix/BC_EncoderContext.h new file mode 100644 index 0000000000..ddc6988dc3 --- /dev/null +++ b/xfa/fxbarcode/datamatrix/BC_EncoderContext.h @@ -0,0 +1,55 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef XFA_FXBARCODE_DATAMATRIX_BC_ENCODERCONTEXT_H_ +#define XFA_FXBARCODE_DATAMATRIX_BC_ENCODERCONTEXT_H_ + +#include "xfa/fxbarcode/datamatrix/BC_SymbolShapeHint.h" + +class CBC_SymbolInfo; +class CBC_Dimension; + +class CBC_EncoderContext : public CBC_SymbolShapeHint { + public: + CBC_EncoderContext(const CFX_WideString msg, + CFX_WideString ecLevel, + int32_t& e); + virtual ~CBC_EncoderContext(); + void setSymbolShape(SymbolShapeHint shape); + void setSizeConstraints(CBC_Dimension* minSize, CBC_Dimension* maxSize); + CFX_WideString getMessage(); + void setSkipAtEnd(int32_t count); + FX_WCHAR getCurrentChar(); + FX_WCHAR getCurrent(); + void writeCodewords(CFX_WideString codewords); + void writeCodeword(FX_WCHAR codeword); + int32_t getCodewordCount(); + void signalEncoderChange(int32_t encoding); + void resetEncoderSignal(); + FX_BOOL hasMoreCharacters(); + int32_t getRemainingCharacters(); + void updateSymbolInfo(int32_t& e); + void updateSymbolInfo(int32_t len, int32_t& e); + void resetSymbolInfo(); + + public: + CFX_WideString m_msg; + CFX_WideString m_codewords; + int32_t m_pos; + int32_t m_newEncoding; + CBC_SymbolInfo* m_symbolInfo; + + private: + int32_t getTotalMessageCharCount(); + + private: + SymbolShapeHint m_shape; + CBC_Dimension* m_minSize; + CBC_Dimension* m_maxSize; + int32_t m_skipAtEnd; +}; + +#endif // XFA_FXBARCODE_DATAMATRIX_BC_ENCODERCONTEXT_H_ diff --git a/xfa/fxbarcode/datamatrix/BC_ErrorCorrection.cpp b/xfa/fxbarcode/datamatrix/BC_ErrorCorrection.cpp new file mode 100644 index 0000000000..98c0599e50 --- /dev/null +++ b/xfa/fxbarcode/datamatrix/BC_ErrorCorrection.cpp @@ -0,0 +1,175 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com +// Original code is licensed as follows: +/* + * Copyright 2006 Jeremias Maerki. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "xfa/fxbarcode/datamatrix/BC_Encoder.h" +#include "xfa/fxbarcode/datamatrix/BC_ErrorCorrection.h" +#include "xfa/fxbarcode/datamatrix/BC_SymbolInfo.h" +#include "xfa/fxbarcode/datamatrix/BC_SymbolShapeHint.h" + +int32_t CBC_ErrorCorrection::FACTOR_SETS[] = {5, 7, 10, 11, 12, 14, 18, 20, + 24, 28, 36, 42, 48, 56, 62, 68}; +int32_t CBC_ErrorCorrection::FACTORS[][100] = { + {228, 48, 15, 111, 62}, + {23, 68, 144, 134, 240, 92, 254}, + {28, 24, 185, 166, 223, 248, 116, 255, 110, 61}, + {175, 138, 205, 12, 194, 168, 39, 245, 60, 97, 120}, + {41, 153, 158, 91, 61, 42, 142, 213, 97, 178, 100, 242}, + {156, 97, 192, 252, 95, 9, 157, 119, 138, 45, 18, 186, 83, 185}, + {83, 195, 100, 39, 188, 75, 66, 61, 241, 213, 109, 129, 94, 254, 225, 48, + 90, 188}, + {15, 195, 244, 9, 233, 71, 168, 2, 188, 160, 153, 145, 253, 79, 108, 82, 27, + 174, 186, 172}, + {52, 190, 88, 205, 109, 39, 176, 21, 155, 197, 251, 223, 155, 21, 5, 172, + 254, 124, 12, 181, 184, 96, 50, 193}, + {211, 231, 43, 97, 71, 96, 103, 174, 37, 151, 170, 53, 75, 34, 249, 121, 17, + 138, 110, 213, 141, 136, 120, 151, 233, 168, 93, 255}, + {245, 127, 242, 218, 130, 250, 162, 181, 102, 120, 84, 179, 220, 251, 80, + 182, 229, 18, 2, 4, 68, 33, 101, 137, 95, 119, 115, 44, 175, 184, 59, 25, + 225, 98, 81, 112}, + {77, 193, 137, 31, 19, 38, 22, 153, 247, 105, 122, 2, 245, 133, 242, 8, 175, + 95, 100, 9, 167, 105, 214, 111, 57, 121, 21, 1, 253, 57, 54, 101, 248, 202, + 69, 50, 150, 177, 226, 5, 9, 5}, + {245, 132, 172, 223, 96, 32, 117, 22, 238, 133, 238, 231, 205, 188, 237, 87, + 191, 106, 16, 147, 118, 23, 37, 90, 170, 205, 131, 88, 120, 100, 66, 138, + 186, 240, 82, 44, 176, 87, 187, 147, 160, 175, 69, 213, 92, 253, 225, 19}, + {175, 9, 223, 238, 12, 17, 220, 208, 100, 29, 175, 170, 230, 192, 215, 235, + 150, 159, 36, 223, 38, 200, 132, 54, 228, 146, 218, 234, 117, 203, 29, 232, + 144, 238, 22, 150, 201, 117, 62, 207, 164, 13, 137, 245, 127, 67, 247, 28, + 155, 43, 203, 107, 233, 53, 143, 46}, + {242, 93, 169, 50, 144, 210, 39, 118, 202, 188, 201, 189, 143, 108, 196, 37, + 185, 112, 134, 230, 245, 63, 197, 190, 250, 106, 185, 221, 175, 64, 114, + 71, 161, 44, 147, 6, 27, 218, 51, 63, 87, 10, 40, 130, 188, 17, 163, 31, + 176, 170, 4, 107, 232, 7, 94, 166, 224, 124, 86, 47, 11, 204}, + {220, 228, 173, 89, 251, 149, 159, 56, 89, 33, 147, 244, 154, 36, 73, 127, + 213, 136, 248, 180, 234, 197, 158, 177, 68, 122, 93, 213, 15, 160, 227, + 236, 66, 139, 153, 185, 202, 167, 179, 25, 220, 232, 96, 210, 231, 136, + 223, 239, 181, 241, 59, 52, 172, 25, 49, 232, 211, 189, 64, 54, 108, 153, + 132, 63, 96, 103, 82, 186}}; +int32_t CBC_ErrorCorrection::MODULO_VALUE = 0x12D; +int32_t CBC_ErrorCorrection::LOG[256] = {0}; +int32_t CBC_ErrorCorrection::ALOG[256] = {0}; +void CBC_ErrorCorrection::Initialize() { + int32_t p = 1; + for (int32_t i = 0; i < 255; i++) { + ALOG[i] = p; + LOG[p] = i; + p <<= 1; + if (p >= 256) { + p ^= MODULO_VALUE; + } + } +} +void CBC_ErrorCorrection::Finalize() {} +CBC_ErrorCorrection::CBC_ErrorCorrection() {} +CBC_ErrorCorrection::~CBC_ErrorCorrection() {} +CFX_WideString CBC_ErrorCorrection::encodeECC200(CFX_WideString codewords, + CBC_SymbolInfo* symbolInfo, + int32_t& e) { + if (codewords.GetLength() != symbolInfo->m_dataCapacity) { + e = BCExceptionIllegalArgument; + return (FX_WCHAR*)""; + } + CFX_WideString sb; + sb += codewords; + int32_t blockCount = symbolInfo->getInterleavedBlockCount(); + if (blockCount == 1) { + CFX_WideString ecc = + createECCBlock(codewords, symbolInfo->m_errorCodewords, e); + BC_EXCEPTION_CHECK_ReturnValue(e, (FX_WCHAR*)""); + sb += ecc; + } else { + CFX_Int32Array dataSizes; + dataSizes.SetSize(blockCount); + CFX_Int32Array errorSizes; + errorSizes.SetSize(blockCount); + CFX_Int32Array startPos; + startPos.SetSize(blockCount); + for (int32_t i = 0; i < blockCount; i++) { + dataSizes[i] = symbolInfo->getDataLengthForInterleavedBlock(i + 1); + errorSizes[i] = symbolInfo->getErrorLengthForInterleavedBlock(i + 1); + startPos[i] = 0; + if (i > 0) { + startPos[i] = startPos[i - 1] + dataSizes[i]; + } + } + for (int32_t block = 0; block < blockCount; block++) { + CFX_WideString temp; + for (int32_t d = block; d < symbolInfo->m_dataCapacity; d += blockCount) { + temp += (FX_WCHAR)codewords.GetAt(d); + } + CFX_WideString ecc = createECCBlock(temp, errorSizes[block], e); + BC_EXCEPTION_CHECK_ReturnValue(e, (FX_WCHAR*)""); + int32_t pos = 0; + for (int32_t l = block; l < errorSizes[block] * blockCount; + l += blockCount) { + sb.SetAt(symbolInfo->m_dataCapacity + l, ecc.GetAt(pos++)); + } + } + } + return sb; +} +CFX_WideString CBC_ErrorCorrection::createECCBlock(CFX_WideString codewords, + int32_t numECWords, + int32_t& e) { + return createECCBlock(codewords, 0, codewords.GetLength(), numECWords, e); +} +CFX_WideString CBC_ErrorCorrection::createECCBlock(CFX_WideString codewords, + int32_t start, + int32_t len, + int32_t numECWords, + int32_t& e) { + int32_t table = -1; + for (int32_t i = 0; i < sizeof(FACTOR_SETS) / sizeof(int32_t); i++) { + if (FACTOR_SETS[i] == numECWords) { + table = i; + break; + } + } + if (table < 0) { + e = BCExceptionIllegalArgument; + return (FX_WCHAR*)""; + } + FX_WORD* ecc = FX_Alloc(FX_WORD, numECWords); + FXSYS_memset(ecc, 0, numECWords * sizeof(FX_WORD)); + for (int32_t l = start; l < start + len; l++) { + FX_WORD m = ecc[numECWords - 1] ^ codewords.GetAt(l); + for (int32_t k = numECWords - 1; k > 0; k--) { + if (m != 0 && FACTORS[table][k] != 0) { + ecc[k] = (FX_WORD)(ecc[k - 1] ^ + ALOG[(LOG[m] + LOG[FACTORS[table][k]]) % 255]); + } else { + ecc[k] = ecc[k - 1]; + } + } + if (m != 0 && FACTORS[table][0] != 0) { + ecc[0] = (FX_WORD)ALOG[(LOG[m] + LOG[FACTORS[table][0]]) % 255]; + } else { + ecc[0] = 0; + } + } + CFX_WideString strecc; + for (int32_t j = 0; j < numECWords; j++) { + strecc += (FX_WCHAR)ecc[numECWords - j - 1]; + } + FX_Free(ecc); + return strecc; +} diff --git a/xfa/fxbarcode/datamatrix/BC_ErrorCorrection.h b/xfa/fxbarcode/datamatrix/BC_ErrorCorrection.h new file mode 100644 index 0000000000..a4264b6306 --- /dev/null +++ b/xfa/fxbarcode/datamatrix/BC_ErrorCorrection.h @@ -0,0 +1,39 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef XFA_FXBARCODE_DATAMATRIX_BC_ERRORCORRECTION_H_ +#define XFA_FXBARCODE_DATAMATRIX_BC_ERRORCORRECTION_H_ + +class CBC_SymbolInfo; +class CBC_ErrorCorrection { + public: + CBC_ErrorCorrection(); + virtual ~CBC_ErrorCorrection(); + static void Initialize(); + static void Finalize(); + static CFX_WideString encodeECC200(CFX_WideString codewords, + CBC_SymbolInfo* symbolInfo, + int32_t& e); + + private: + static int32_t FACTOR_SETS[]; + static int32_t FACTORS[][100]; + static int32_t MODULO_VALUE; + static int32_t LOG[256]; + static int32_t ALOG[256]; + + private: + static CFX_WideString createECCBlock(CFX_WideString codewords, + int32_t numECWords, + int32_t& e); + static CFX_WideString createECCBlock(CFX_WideString codewords, + int32_t start, + int32_t len, + int32_t numECWords, + int32_t& e); +}; + +#endif // XFA_FXBARCODE_DATAMATRIX_BC_ERRORCORRECTION_H_ diff --git a/xfa/fxbarcode/datamatrix/BC_HighLevelEncoder.cpp b/xfa/fxbarcode/datamatrix/BC_HighLevelEncoder.cpp new file mode 100644 index 0000000000..d8e7bb1dc5 --- /dev/null +++ b/xfa/fxbarcode/datamatrix/BC_HighLevelEncoder.cpp @@ -0,0 +1,375 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com +// Original code is licensed as follows: +/* + * Copyright 2006-2007 Jeremias Maerki. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <limits> + +#include "xfa/fxbarcode/BC_Dimension.h" +#include "xfa/fxbarcode/BC_UtilCodingConvert.h" +#include "xfa/fxbarcode/common/BC_CommonBitMatrix.h" +#include "xfa/fxbarcode/datamatrix/BC_ASCIIEncoder.h" +#include "xfa/fxbarcode/datamatrix/BC_Base256Encoder.h" +#include "xfa/fxbarcode/datamatrix/BC_C40Encoder.h" +#include "xfa/fxbarcode/datamatrix/BC_EdifactEncoder.h" +#include "xfa/fxbarcode/datamatrix/BC_Encoder.h" +#include "xfa/fxbarcode/datamatrix/BC_EncoderContext.h" +#include "xfa/fxbarcode/datamatrix/BC_HighLevelEncoder.h" +#include "xfa/fxbarcode/datamatrix/BC_SymbolInfo.h" +#include "xfa/fxbarcode/datamatrix/BC_SymbolShapeHint.h" +#include "xfa/fxbarcode/datamatrix/BC_TextEncoder.h" +#include "xfa/fxbarcode/datamatrix/BC_X12Encoder.h" +#include "xfa/fxbarcode/utils.h" + +FX_WCHAR CBC_HighLevelEncoder::LATCH_TO_C40 = 230; +FX_WCHAR CBC_HighLevelEncoder::LATCH_TO_BASE256 = 231; +FX_WCHAR CBC_HighLevelEncoder::UPPER_SHIFT = 235; +FX_WCHAR CBC_HighLevelEncoder::LATCH_TO_ANSIX12 = 238; +FX_WCHAR CBC_HighLevelEncoder::LATCH_TO_TEXT = 239; +FX_WCHAR CBC_HighLevelEncoder::LATCH_TO_EDIFACT = 240; +FX_WCHAR CBC_HighLevelEncoder::C40_UNLATCH = 254; +FX_WCHAR CBC_HighLevelEncoder::X12_UNLATCH = 254; +FX_WCHAR CBC_HighLevelEncoder::PAD = 129; +FX_WCHAR CBC_HighLevelEncoder::MACRO_05 = 236; +FX_WCHAR CBC_HighLevelEncoder::MACRO_06 = 237; +const wchar_t* CBC_HighLevelEncoder::MACRO_05_HEADER = L"[)>05"; +const wchar_t* CBC_HighLevelEncoder::MACRO_06_HEADER = L"[)>06"; +const wchar_t CBC_HighLevelEncoder::MACRO_TRAILER = 0x0004; + +CBC_HighLevelEncoder::CBC_HighLevelEncoder() {} +CBC_HighLevelEncoder::~CBC_HighLevelEncoder() {} +CFX_ByteArray& CBC_HighLevelEncoder::getBytesForMessage(CFX_WideString msg) { + CFX_ByteString bytestr; + CBC_UtilCodingConvert::UnicodeToUTF8(msg, bytestr); + for (int32_t i = 0; i < bytestr.GetLength(); i++) { + m_bytearray.Add(bytestr.GetAt(i)); + } + return m_bytearray; +} +CFX_WideString CBC_HighLevelEncoder::encodeHighLevel(CFX_WideString msg, + CFX_WideString ecLevel, + int32_t& e) { + return encodeHighLevel(msg, ecLevel, FORCE_NONE, NULL, NULL, e); +} +CFX_WideString CBC_HighLevelEncoder::encodeHighLevel(CFX_WideString msg, + CFX_WideString ecLevel, + SymbolShapeHint shape, + CBC_Dimension* minSize, + CBC_Dimension* maxSize, + int32_t& e) { + CBC_EncoderContext context(msg, ecLevel, e); + BC_EXCEPTION_CHECK_ReturnValue(e, (FX_WCHAR*)""); + context.setSymbolShape(shape); + context.setSizeConstraints(minSize, maxSize); + if ((msg.Mid(0, 6) == MACRO_05_HEADER) && + (msg.Mid(msg.GetLength() - 1, 1) == MACRO_TRAILER)) { + context.writeCodeword(MACRO_05); + context.setSkipAtEnd(2); + context.m_pos += 6; + } else if ((msg.Mid(0, 6) == MACRO_06_HEADER) && + (msg.Mid(msg.GetLength() - 1, 1) == MACRO_TRAILER)) { + context.writeCodeword(MACRO_06); + context.setSkipAtEnd(2); + context.m_pos += 6; + } + CFX_PtrArray encoders; + encoders.Add(new CBC_ASCIIEncoder()); + encoders.Add(new CBC_C40Encoder()); + encoders.Add(new CBC_TextEncoder()); + encoders.Add(new CBC_X12Encoder()); + encoders.Add(new CBC_EdifactEncoder()); + encoders.Add(new CBC_Base256Encoder()); + int32_t encodingMode = ASCII_ENCODATION; + while (context.hasMoreCharacters()) { + ((CBC_Encoder*)encoders.GetAt(encodingMode))->Encode(context, e); + if (e != BCExceptionNO) { + for (int32_t i = 0; i < encoders.GetSize(); i++) { + delete (CBC_Encoder*)encoders.GetAt(i); + } + encoders.RemoveAll(); + return (FX_WCHAR*)""; + } + if (context.m_newEncoding >= 0) { + encodingMode = context.m_newEncoding; + context.resetEncoderSignal(); + } + } + int32_t len = context.m_codewords.GetLength(); + context.updateSymbolInfo(e); + if (e != BCExceptionNO) { + for (int32_t i = 0; i < encoders.GetSize(); i++) { + delete (CBC_Encoder*)encoders.GetAt(i); + } + encoders.RemoveAll(); + return (FX_WCHAR*)""; + } + int32_t capacity = context.m_symbolInfo->m_dataCapacity; + if (len < capacity) { + if (encodingMode != ASCII_ENCODATION && + encodingMode != BASE256_ENCODATION) { + context.writeCodeword(0x00fe); + } + } + CFX_WideString codewords = context.m_codewords; + if (codewords.GetLength() < capacity) { + codewords += PAD; + } + while (codewords.GetLength() < capacity) { + codewords += (randomize253State(PAD, codewords.GetLength() + 1)); + } + for (int32_t i = 0; i < encoders.GetSize(); i++) { + delete (CBC_Encoder*)encoders.GetAt(i); + } + encoders.RemoveAll(); + return codewords; +} +int32_t CBC_HighLevelEncoder::lookAheadTest(CFX_WideString msg, + int32_t startpos, + int32_t currentMode) { + if (startpos >= msg.GetLength()) { + return currentMode; + } + CFX_FloatArray charCounts; + if (currentMode == ASCII_ENCODATION) { + charCounts.Add(0); + charCounts.Add(1); + charCounts.Add(1); + charCounts.Add(1); + charCounts.Add(1); + charCounts.Add(1.25f); + } else { + charCounts.Add(1); + charCounts.Add(2); + charCounts.Add(2); + charCounts.Add(2); + charCounts.Add(2); + charCounts.Add(2.25f); + charCounts[currentMode] = 0; + } + int32_t charsProcessed = 0; + while (TRUE) { + if ((startpos + charsProcessed) == msg.GetLength()) { + FX_DWORD min = std::numeric_limits<int32_t>::max(); + CFX_ByteArray mins; + mins.SetSize(6); + CFX_Int32Array intCharCounts; + intCharCounts.SetSize(6); + min = findMinimums(charCounts, intCharCounts, min, mins); + int32_t minCount = getMinimumCount(mins); + if (intCharCounts[ASCII_ENCODATION] == min) { + return ASCII_ENCODATION; + } + if (minCount == 1 && mins[BASE256_ENCODATION] > 0) { + return BASE256_ENCODATION; + } + if (minCount == 1 && mins[EDIFACT_ENCODATION] > 0) { + return EDIFACT_ENCODATION; + } + if (minCount == 1 && mins[TEXT_ENCODATION] > 0) { + return TEXT_ENCODATION; + } + if (minCount == 1 && mins[X12_ENCODATION] > 0) { + return X12_ENCODATION; + } + return C40_ENCODATION; + } + FX_WCHAR c = msg.GetAt(startpos + charsProcessed); + charsProcessed++; + if (isDigit(c)) { + charCounts[ASCII_ENCODATION] += 0.5; + } else if (isExtendedASCII(c)) { + charCounts[ASCII_ENCODATION] = + (FX_FLOAT)ceil(charCounts[ASCII_ENCODATION]); + charCounts[ASCII_ENCODATION] += 2; + } else { + charCounts[ASCII_ENCODATION] = + (FX_FLOAT)ceil(charCounts[ASCII_ENCODATION]); + charCounts[ASCII_ENCODATION]++; + } + if (isNativeC40(c)) { + charCounts[C40_ENCODATION] += 2.0f / 3.0f; + } else if (isExtendedASCII(c)) { + charCounts[C40_ENCODATION] += 8.0f / 3.0f; + } else { + charCounts[C40_ENCODATION] += 4.0f / 3.0f; + } + if (isNativeText(c)) { + charCounts[TEXT_ENCODATION] += 2.0f / 3.0f; + } else if (isExtendedASCII(c)) { + charCounts[TEXT_ENCODATION] += 8.0f / 3.0f; + } else { + charCounts[TEXT_ENCODATION] += 4.0f / 3.0f; + } + if (isNativeX12(c)) { + charCounts[X12_ENCODATION] += 2.0f / 3.0f; + } else if (isExtendedASCII(c)) { + charCounts[X12_ENCODATION] += 13.0f / 3.0f; + } else { + charCounts[X12_ENCODATION] += 10.0f / 3.0f; + } + if (isNativeEDIFACT(c)) { + charCounts[EDIFACT_ENCODATION] += 3.0f / 4.0f; + } else if (isExtendedASCII(c)) { + charCounts[EDIFACT_ENCODATION] += 17.0f / 4.0f; + } else { + charCounts[EDIFACT_ENCODATION] += 13.0f / 4.0f; + } + if (isSpecialB256(c)) { + charCounts[BASE256_ENCODATION] += 4; + } else { + charCounts[BASE256_ENCODATION]++; + } + if (charsProcessed >= 4) { + CFX_Int32Array intCharCounts; + intCharCounts.SetSize(6); + CFX_ByteArray mins; + mins.SetSize(6); + findMinimums(charCounts, intCharCounts, + std::numeric_limits<int32_t>::max(), mins); + int32_t minCount = getMinimumCount(mins); + if (intCharCounts[ASCII_ENCODATION] < intCharCounts[BASE256_ENCODATION] && + intCharCounts[ASCII_ENCODATION] < intCharCounts[C40_ENCODATION] && + intCharCounts[ASCII_ENCODATION] < intCharCounts[TEXT_ENCODATION] && + intCharCounts[ASCII_ENCODATION] < intCharCounts[X12_ENCODATION] && + intCharCounts[ASCII_ENCODATION] < intCharCounts[EDIFACT_ENCODATION]) { + return ASCII_ENCODATION; + } + if (intCharCounts[BASE256_ENCODATION] < intCharCounts[ASCII_ENCODATION] || + (mins[C40_ENCODATION] + mins[TEXT_ENCODATION] + mins[X12_ENCODATION] + + mins[EDIFACT_ENCODATION]) == 0) { + return BASE256_ENCODATION; + } + if (minCount == 1 && mins[EDIFACT_ENCODATION] > 0) { + return EDIFACT_ENCODATION; + } + if (minCount == 1 && mins[TEXT_ENCODATION] > 0) { + return TEXT_ENCODATION; + } + if (minCount == 1 && mins[X12_ENCODATION] > 0) { + return X12_ENCODATION; + } + if (intCharCounts[C40_ENCODATION] + 1 < intCharCounts[ASCII_ENCODATION] && + intCharCounts[C40_ENCODATION] + 1 < + intCharCounts[BASE256_ENCODATION] && + intCharCounts[C40_ENCODATION] + 1 < + intCharCounts[EDIFACT_ENCODATION] && + intCharCounts[C40_ENCODATION] + 1 < intCharCounts[TEXT_ENCODATION]) { + if (intCharCounts[C40_ENCODATION] < intCharCounts[X12_ENCODATION]) { + return C40_ENCODATION; + } + if (intCharCounts[C40_ENCODATION] == intCharCounts[X12_ENCODATION]) { + int32_t p = startpos + charsProcessed + 1; + while (p < msg.GetLength()) { + FX_WCHAR tc = msg.GetAt(p); + if (isX12TermSep(tc)) { + return X12_ENCODATION; + } + if (!isNativeX12(tc)) { + break; + } + p++; + } + return C40_ENCODATION; + } + } + } + } +} +FX_BOOL CBC_HighLevelEncoder::isDigit(FX_WCHAR ch) { + return ch >= '0' && ch <= '9'; +} +FX_BOOL CBC_HighLevelEncoder::isExtendedASCII(FX_WCHAR ch) { + return ch >= 128 && ch <= 255; +} +int32_t CBC_HighLevelEncoder::determineConsecutiveDigitCount(CFX_WideString msg, + int32_t startpos) { + int32_t count = 0; + int32_t len = msg.GetLength(); + int32_t idx = startpos; + if (idx < len) { + FX_WCHAR ch = msg.GetAt(idx); + while (isDigit(ch) && idx < len) { + count++; + idx++; + if (idx < len) { + ch = msg.GetAt(idx); + } + } + } + return count; +} +void CBC_HighLevelEncoder::illegalCharacter(FX_WCHAR c, int32_t& e) { + e = BCExceptionIllegalArgument; +} +FX_WCHAR CBC_HighLevelEncoder::randomize253State(FX_WCHAR ch, + int32_t codewordPosition) { + int32_t pseudoRandom = ((149 * codewordPosition) % 253) + 1; + int32_t tempVariable = ch + pseudoRandom; + return tempVariable <= 254 ? (FX_WCHAR)tempVariable + : (FX_WCHAR)(tempVariable - 254); +} +int32_t CBC_HighLevelEncoder::findMinimums(CFX_FloatArray& charCounts, + CFX_Int32Array& intCharCounts, + int32_t min, + CFX_ByteArray& mins) { + for (int32_t l = 0; l < mins.GetSize(); l++) { + mins[l] = (uint8_t)0; + } + for (int32_t i = 0; i < 6; i++) { + intCharCounts[i] = (int32_t)ceil(charCounts[i]); + int32_t current = intCharCounts[i]; + if (min > current) { + min = current; + for (int32_t j = 0; j < mins.GetSize(); j++) { + mins[j] = (uint8_t)0; + } + } + if (min == current) { + mins[i]++; + } + } + return min; +} +int32_t CBC_HighLevelEncoder::getMinimumCount(CFX_ByteArray& mins) { + int32_t minCount = 0; + for (int32_t i = 0; i < 6; i++) { + minCount += mins[i]; + } + return minCount; +} +FX_BOOL CBC_HighLevelEncoder::isNativeC40(FX_WCHAR ch) { + return (ch == ' ') || (ch >= '0' && ch <= '9') || (ch >= 'A' && ch <= 'Z'); +} +FX_BOOL CBC_HighLevelEncoder::isNativeText(FX_WCHAR ch) { + return (ch == ' ') || (ch >= '0' && ch <= '9') || (ch >= 'a' && ch <= 'z'); +} +FX_BOOL CBC_HighLevelEncoder::isNativeX12(FX_WCHAR ch) { + return isX12TermSep(ch) || (ch == ' ') || (ch >= '0' && ch <= '9') || + (ch >= 'A' && ch <= 'Z'); +} +FX_BOOL CBC_HighLevelEncoder::isX12TermSep(FX_WCHAR ch) { + return (ch == '\r') || (ch == '*') || (ch == '>'); +} +FX_BOOL CBC_HighLevelEncoder::isNativeEDIFACT(FX_WCHAR ch) { + return ch >= ' ' && ch <= '^'; +} +FX_BOOL CBC_HighLevelEncoder::isSpecialB256(FX_WCHAR ch) { + return FALSE; +} diff --git a/xfa/fxbarcode/datamatrix/BC_HighLevelEncoder.h b/xfa/fxbarcode/datamatrix/BC_HighLevelEncoder.h new file mode 100644 index 0000000000..0aad4d4da5 --- /dev/null +++ b/xfa/fxbarcode/datamatrix/BC_HighLevelEncoder.h @@ -0,0 +1,76 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef XFA_FXBARCODE_DATAMATRIX_BC_HIGHLEVELENCODER_H_ +#define XFA_FXBARCODE_DATAMATRIX_BC_HIGHLEVELENCODER_H_ + +#include "xfa/fxbarcode/datamatrix/BC_SymbolShapeHint.h" + +#define ASCII_ENCODATION 0 +#define C40_ENCODATION 1 +#define TEXT_ENCODATION 2 +#define X12_ENCODATION 3 +#define EDIFACT_ENCODATION 4 +#define BASE256_ENCODATION 5 + +class CBC_HighLevelEncoder : public CBC_SymbolShapeHint { + public: + CBC_HighLevelEncoder(); + virtual ~CBC_HighLevelEncoder(); + CFX_ByteArray& getBytesForMessage(CFX_WideString msg); + static CFX_WideString encodeHighLevel(CFX_WideString msg, + CFX_WideString ecLevel, + int32_t& e); + static CFX_WideString encodeHighLevel(CFX_WideString msg, + CFX_WideString ecLevel, + SymbolShapeHint shape, + CBC_Dimension* minSize, + CBC_Dimension* maxSize, + int32_t& e); + static int32_t lookAheadTest(CFX_WideString msg, + int32_t startpos, + int32_t currentMode); + static FX_BOOL isDigit(FX_WCHAR ch); + static FX_BOOL isExtendedASCII(FX_WCHAR ch); + static int32_t determineConsecutiveDigitCount(CFX_WideString msg, + int32_t startpos); + static void illegalCharacter(FX_WCHAR c, int32_t& e); + + public: + static FX_WCHAR LATCH_TO_C40; + static FX_WCHAR LATCH_TO_BASE256; + static FX_WCHAR UPPER_SHIFT; + static FX_WCHAR LATCH_TO_ANSIX12; + static FX_WCHAR LATCH_TO_TEXT; + static FX_WCHAR LATCH_TO_EDIFACT; + static FX_WCHAR C40_UNLATCH; + static FX_WCHAR X12_UNLATCH; + + private: + static FX_WCHAR PAD; + static FX_WCHAR MACRO_05; + static FX_WCHAR MACRO_06; + static const wchar_t* MACRO_05_HEADER; + static const wchar_t* MACRO_06_HEADER; + static const wchar_t MACRO_TRAILER; + CFX_ByteArray m_bytearray; + + private: + static FX_WCHAR randomize253State(FX_WCHAR ch, int32_t codewordPosition); + static int32_t findMinimums(CFX_FloatArray& charCounts, + CFX_Int32Array& intCharCounts, + int32_t min, + CFX_ByteArray& mins); + static int32_t getMinimumCount(CFX_ByteArray& mins); + static FX_BOOL isNativeC40(FX_WCHAR ch); + static FX_BOOL isNativeText(FX_WCHAR ch); + static FX_BOOL isNativeX12(FX_WCHAR ch); + static FX_BOOL isX12TermSep(FX_WCHAR ch); + static FX_BOOL isNativeEDIFACT(FX_WCHAR ch); + static FX_BOOL isSpecialB256(FX_WCHAR ch); +}; + +#endif // XFA_FXBARCODE_DATAMATRIX_BC_HIGHLEVELENCODER_H_ diff --git a/xfa/fxbarcode/datamatrix/BC_SymbolInfo.cpp b/xfa/fxbarcode/datamatrix/BC_SymbolInfo.cpp new file mode 100644 index 0000000000..593f4cb162 --- /dev/null +++ b/xfa/fxbarcode/datamatrix/BC_SymbolInfo.cpp @@ -0,0 +1,255 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com +// Original code is licensed as follows: +/* + * Copyright 2006 Jeremias Maerki + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "xfa/fxbarcode/BC_Dimension.h" +#include "xfa/fxbarcode/common/BC_CommonBitMatrix.h" +#include "xfa/fxbarcode/datamatrix/BC_DataMatrixSymbolInfo144.h" +#include "xfa/fxbarcode/datamatrix/BC_Encoder.h" +#include "xfa/fxbarcode/datamatrix/BC_SymbolInfo.h" +#include "xfa/fxbarcode/datamatrix/BC_SymbolShapeHint.h" + +#define SYMBOLS_COUNT 30 + +CBC_SymbolInfo* CBC_SymbolInfo::m_PROD_SYMBOLS[30] = { + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}; +CBC_SymbolInfo* CBC_SymbolInfo::m_symbols[30] = { + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}; +void CBC_SymbolInfo::Initialize() { + m_PROD_SYMBOLS[0] = new CBC_SymbolInfo(FALSE, 3, 5, 8, 8, 1); + m_PROD_SYMBOLS[1] = new CBC_SymbolInfo(FALSE, 5, 7, 10, 10, 1); + m_PROD_SYMBOLS[2] = new CBC_SymbolInfo(TRUE, 5, 7, 16, 6, 1); + m_PROD_SYMBOLS[3] = new CBC_SymbolInfo(FALSE, 8, 10, 12, 12, 1); + m_PROD_SYMBOLS[4] = new CBC_SymbolInfo(TRUE, 10, 11, 14, 6, 2); + m_PROD_SYMBOLS[5] = new CBC_SymbolInfo(FALSE, 12, 12, 14, 14, 1); + m_PROD_SYMBOLS[6] = new CBC_SymbolInfo(TRUE, 16, 14, 24, 10, 1); + m_PROD_SYMBOLS[7] = new CBC_SymbolInfo(FALSE, 18, 14, 16, 16, 1); + m_PROD_SYMBOLS[8] = new CBC_SymbolInfo(FALSE, 22, 18, 18, 18, 1); + m_PROD_SYMBOLS[9] = new CBC_SymbolInfo(TRUE, 22, 18, 16, 10, 2); + m_PROD_SYMBOLS[10] = new CBC_SymbolInfo(FALSE, 30, 20, 20, 20, 1); + m_PROD_SYMBOLS[11] = new CBC_SymbolInfo(TRUE, 32, 24, 16, 14, 2); + m_PROD_SYMBOLS[12] = new CBC_SymbolInfo(FALSE, 36, 24, 22, 22, 1); + m_PROD_SYMBOLS[13] = new CBC_SymbolInfo(FALSE, 44, 28, 24, 24, 1); + m_PROD_SYMBOLS[14] = new CBC_SymbolInfo(TRUE, 49, 28, 22, 14, 2); + m_PROD_SYMBOLS[15] = new CBC_SymbolInfo(FALSE, 62, 36, 14, 14, 4); + m_PROD_SYMBOLS[16] = new CBC_SymbolInfo(FALSE, 86, 42, 16, 16, 4); + m_PROD_SYMBOLS[17] = new CBC_SymbolInfo(FALSE, 114, 48, 18, 18, 4); + m_PROD_SYMBOLS[18] = new CBC_SymbolInfo(FALSE, 144, 56, 20, 20, 4); + m_PROD_SYMBOLS[19] = new CBC_SymbolInfo(FALSE, 174, 68, 22, 22, 4); + m_PROD_SYMBOLS[20] = new CBC_SymbolInfo(FALSE, 204, 84, 24, 24, 4, 102, 42); + m_PROD_SYMBOLS[21] = new CBC_SymbolInfo(FALSE, 280, 112, 14, 14, 16, 140, 56); + m_PROD_SYMBOLS[22] = new CBC_SymbolInfo(FALSE, 368, 144, 16, 16, 16, 92, 36); + m_PROD_SYMBOLS[23] = new CBC_SymbolInfo(FALSE, 456, 192, 18, 18, 16, 114, 48); + m_PROD_SYMBOLS[24] = new CBC_SymbolInfo(FALSE, 576, 224, 20, 20, 16, 144, 56); + m_PROD_SYMBOLS[25] = new CBC_SymbolInfo(FALSE, 696, 272, 22, 22, 16, 174, 68); + m_PROD_SYMBOLS[26] = new CBC_SymbolInfo(FALSE, 816, 336, 24, 24, 16, 136, 56); + m_PROD_SYMBOLS[27] = + new CBC_SymbolInfo(FALSE, 1050, 408, 18, 18, 36, 175, 68); + m_PROD_SYMBOLS[28] = + new CBC_SymbolInfo(FALSE, 1304, 496, 20, 20, 36, 163, 62); + m_PROD_SYMBOLS[29] = new CBC_DataMatrixSymbolInfo144(); + for (int32_t i = 0; i < SYMBOLS_COUNT; i++) { + m_symbols[i] = m_PROD_SYMBOLS[i]; + } +} +void CBC_SymbolInfo::Finalize() { + for (int32_t i = 0; i < SYMBOLS_COUNT; i++) { + delete m_PROD_SYMBOLS[i]; + m_PROD_SYMBOLS[i] = NULL; + m_symbols[i] = NULL; + } +} +CBC_SymbolInfo::CBC_SymbolInfo(FX_BOOL rectangular, + int32_t dataCapacity, + int32_t errorCodewords, + int32_t matrixWidth, + int32_t matrixHeight, + int32_t dataRegions) { + m_rectangular = rectangular; + m_dataCapacity = dataCapacity; + m_errorCodewords = errorCodewords; + m_matrixWidth = matrixWidth; + m_matrixHeight = matrixHeight; + m_dataRegions = dataRegions; + m_rsBlockData = dataCapacity; + m_rsBlockError = errorCodewords; +} +CBC_SymbolInfo::CBC_SymbolInfo(FX_BOOL rectangular, + int32_t dataCapacity, + int32_t errorCodewords, + int32_t matrixWidth, + int32_t matrixHeight, + int32_t dataRegions, + int32_t rsBlockData, + int32_t rsBlockError) { + m_rectangular = rectangular; + m_dataCapacity = dataCapacity; + m_errorCodewords = errorCodewords; + m_matrixWidth = matrixWidth; + m_matrixHeight = matrixHeight; + m_dataRegions = dataRegions; + m_rsBlockData = rsBlockData; + m_rsBlockError = rsBlockError; +} +CBC_SymbolInfo::~CBC_SymbolInfo() {} + +CBC_SymbolInfo* CBC_SymbolInfo::lookup(int32_t dataCodewords, int32_t& e) { + return lookup(dataCodewords, FORCE_NONE, TRUE, e); +} +CBC_SymbolInfo* CBC_SymbolInfo::lookup(int32_t dataCodewords, + SymbolShapeHint shape, + int32_t& e) { + return lookup(dataCodewords, shape, TRUE, e); +} +CBC_SymbolInfo* CBC_SymbolInfo::lookup(int32_t dataCodewords, + FX_BOOL allowRectangular, + FX_BOOL fail, + int32_t& e) { + SymbolShapeHint shape = allowRectangular ? FORCE_NONE : FORCE_SQUARE; + return lookup(dataCodewords, shape, fail, e); +} +CBC_SymbolInfo* CBC_SymbolInfo::lookup(int32_t dataCodewords, + SymbolShapeHint shape, + FX_BOOL fail, + int32_t& e) { + return lookup(dataCodewords, shape, NULL, NULL, fail, e); +} +CBC_SymbolInfo* CBC_SymbolInfo::lookup(int32_t dataCodewords, + SymbolShapeHint shape, + CBC_Dimension* minSize, + CBC_Dimension* maxSize, + FX_BOOL fail, + int32_t& e) { + for (int32_t i = 0; i < SYMBOLS_COUNT; i++) { + CBC_SymbolInfo* symbol = m_symbols[i]; + if (shape == FORCE_SQUARE && symbol->m_rectangular) { + continue; + } + if (shape == FORCE_RECTANGLE && !symbol->m_rectangular) { + continue; + } + if (minSize && (symbol->getSymbolWidth(e) < minSize->getWidth() || + symbol->getSymbolHeight(e) < minSize->getHeight())) { + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + continue; + } + if (maxSize && (symbol->getSymbolWidth(e) > maxSize->getWidth() || + symbol->getSymbolHeight(e) > maxSize->getHeight())) { + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + continue; + } + if (dataCodewords <= symbol->m_dataCapacity) { + return symbol; + } + } + if (fail) { + e = BCExceptionIllegalDataCodewords; + return NULL; + } + return NULL; +} +int32_t CBC_SymbolInfo::getHorizontalDataRegions(int32_t& e) { + switch (m_dataRegions) { + case 1: + return 1; + case 2: + return 2; + case 4: + return 2; + case 16: + return 4; + case 36: + return 6; + default: + e = BCExceptionCannotHandleThisNumberOfDataRegions; + return 0; + } +} +int32_t CBC_SymbolInfo::getVerticalDataRegions(int32_t& e) { + switch (m_dataRegions) { + case 1: + return 1; + case 2: + return 1; + case 4: + return 2; + case 16: + return 4; + case 36: + return 6; + default: + e = BCExceptionCannotHandleThisNumberOfDataRegions; + return 0; + } +} +int32_t CBC_SymbolInfo::getSymbolDataWidth(int32_t& e) { + return getHorizontalDataRegions(e) * m_matrixWidth; +} +int32_t CBC_SymbolInfo::getSymbolDataHeight(int32_t& e) { + return getVerticalDataRegions(e) * m_matrixHeight; +} +int32_t CBC_SymbolInfo::getSymbolWidth(int32_t& e) { + return getSymbolDataWidth(e) + (getHorizontalDataRegions(e) * 2); +} +int32_t CBC_SymbolInfo::getSymbolHeight(int32_t& e) { + return getSymbolDataHeight(e) + (getVerticalDataRegions(e) * 2); +} +int32_t CBC_SymbolInfo::getCodewordCount() { + return m_dataCapacity + m_errorCodewords; +} +int32_t CBC_SymbolInfo::getInterleavedBlockCount() { + return m_dataCapacity / m_rsBlockData; +} +int32_t CBC_SymbolInfo::getDataLengthForInterleavedBlock(int32_t index) { + return m_rsBlockData; +} +int32_t CBC_SymbolInfo::getErrorLengthForInterleavedBlock(int32_t index) { + return m_rsBlockError; +} +CFX_WideString CBC_SymbolInfo::toString(int32_t& e) { + CFX_WideString sb; + sb += (FX_WCHAR*)(m_rectangular ? "Rectangular Symbol:" : "Square Symbol:"); + sb += (FX_WCHAR*)" data region "; + sb += m_matrixWidth; + sb += (FX_WCHAR)'x'; + sb += m_matrixHeight; + sb += (FX_WCHAR*)", symbol size "; + sb += getSymbolWidth(e); + BC_EXCEPTION_CHECK_ReturnValue(e, (FX_WCHAR*)""); + sb += (FX_WCHAR)'x'; + sb += getSymbolHeight(e); + BC_EXCEPTION_CHECK_ReturnValue(e, (FX_WCHAR*)""); + sb += (FX_WCHAR*)", symbol data size "; + sb += getSymbolDataWidth(e); + BC_EXCEPTION_CHECK_ReturnValue(e, (FX_WCHAR*)""); + sb += (FX_WCHAR)'x'; + sb += getSymbolDataHeight(e); + BC_EXCEPTION_CHECK_ReturnValue(e, (FX_WCHAR*)""); + sb += (FX_WCHAR*)", codewords "; + sb += m_dataCapacity; + sb += (FX_WCHAR)'+'; + sb += m_errorCodewords; + return sb; +} diff --git a/xfa/fxbarcode/datamatrix/BC_SymbolInfo.h b/xfa/fxbarcode/datamatrix/BC_SymbolInfo.h new file mode 100644 index 0000000000..8f7ed28da9 --- /dev/null +++ b/xfa/fxbarcode/datamatrix/BC_SymbolInfo.h @@ -0,0 +1,83 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef XFA_FXBARCODE_DATAMATRIX_BC_SYMBOLINFO_H_ +#define XFA_FXBARCODE_DATAMATRIX_BC_SYMBOLINFO_H_ + +#include "core/include/fxcrt/fx_string.h" +#include "core/include/fxcrt/fx_system.h" +#include "xfa/fxbarcode/datamatrix/BC_SymbolShapeHint.h" + +class CBC_Dimension; + +class CBC_SymbolInfo : public CBC_SymbolShapeHint { + public: + CBC_SymbolInfo(FX_BOOL rectangular, + int32_t dataCapacity, + int32_t errorCodewords, + int32_t matrixWidth, + int32_t matrixHeight, + int32_t dataRegions); + virtual ~CBC_SymbolInfo(); + static void Initialize(); + static void Finalize(); + static void overrideSymbolSet(CBC_SymbolInfo* override); + static CBC_SymbolInfo* lookup(int32_t dataCodewords, int32_t& e); + static CBC_SymbolInfo* lookup(int32_t dataCodewords, + SymbolShapeHint shape, + int32_t& e); + static CBC_SymbolInfo* lookup(int32_t dataCodewords, + FX_BOOL allowRectangular, + FX_BOOL fail, + int32_t& e); + static CBC_SymbolInfo* lookup(int32_t dataCodewords, + SymbolShapeHint shape, + FX_BOOL fail, + int32_t& e); + static CBC_SymbolInfo* lookup(int32_t dataCodewords, + SymbolShapeHint shape, + CBC_Dimension* minSize, + CBC_Dimension* maxSize, + FX_BOOL fail, + int32_t& e); + int32_t getHorizontalDataRegions(int32_t& e); + int32_t getVerticalDataRegions(int32_t& e); + int32_t getSymbolDataWidth(int32_t& e); + int32_t getSymbolDataHeight(int32_t& e); + int32_t getSymbolWidth(int32_t& e); + int32_t getSymbolHeight(int32_t& e); + int32_t getCodewordCount(); + int32_t getInterleavedBlockCount(); + int32_t getDataLengthForInterleavedBlock(int32_t index); + int32_t getErrorLengthForInterleavedBlock(int32_t index); + CFX_WideString toString(int32_t& e); + + public: + int32_t m_dataCapacity; + int32_t m_errorCodewords; + int32_t m_matrixWidth; + int32_t m_matrixHeight; + int32_t m_rsBlockData; + int32_t m_rsBlockError; + static CBC_SymbolInfo* m_PROD_SYMBOLS[30]; + + private: + static CBC_SymbolInfo* m_symbols[30]; + FX_BOOL m_rectangular; + int32_t m_dataRegions; + + private: + CBC_SymbolInfo(FX_BOOL rectangular, + int32_t dataCapacity, + int32_t errorCodewords, + int32_t matrixWidth, + int32_t matrixHeight, + int32_t dataRegions, + int32_t rsBlockData, + int32_t rsBlockError); +}; + +#endif // XFA_FXBARCODE_DATAMATRIX_BC_SYMBOLINFO_H_ diff --git a/xfa/fxbarcode/datamatrix/BC_SymbolShapeHint.cpp b/xfa/fxbarcode/datamatrix/BC_SymbolShapeHint.cpp new file mode 100644 index 0000000000..8f91dd837a --- /dev/null +++ b/xfa/fxbarcode/datamatrix/BC_SymbolShapeHint.cpp @@ -0,0 +1,26 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com +// Original code is licensed as follows: +/* + * Copyright 2007 Jeremias Maerki. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "xfa/fxbarcode/datamatrix/BC_SymbolShapeHint.h" + +CBC_SymbolShapeHint::CBC_SymbolShapeHint() {} +CBC_SymbolShapeHint::~CBC_SymbolShapeHint() {} diff --git a/xfa/fxbarcode/datamatrix/BC_SymbolShapeHint.h b/xfa/fxbarcode/datamatrix/BC_SymbolShapeHint.h new file mode 100644 index 0000000000..5dfac0516f --- /dev/null +++ b/xfa/fxbarcode/datamatrix/BC_SymbolShapeHint.h @@ -0,0 +1,21 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef XFA_FXBARCODE_DATAMATRIX_BC_SYMBOLSHAPEHINT_H_ +#define XFA_FXBARCODE_DATAMATRIX_BC_SYMBOLSHAPEHINT_H_ + +class CBC_SymbolShapeHint { + public: + CBC_SymbolShapeHint(); + virtual ~CBC_SymbolShapeHint(); + enum SymbolShapeHint { + FORCE_NONE, + FORCE_SQUARE, + FORCE_RECTANGLE, + }; +}; + +#endif // XFA_FXBARCODE_DATAMATRIX_BC_SYMBOLSHAPEHINT_H_ diff --git a/xfa/fxbarcode/datamatrix/BC_TextEncoder.cpp b/xfa/fxbarcode/datamatrix/BC_TextEncoder.cpp new file mode 100644 index 0000000000..c8b37e9c85 --- /dev/null +++ b/xfa/fxbarcode/datamatrix/BC_TextEncoder.cpp @@ -0,0 +1,98 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com +// Original code is licensed as follows: +/* + * Copyright 2006-2007 Jeremias Maerki. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "xfa/fxbarcode/BC_Dimension.h" +#include "xfa/fxbarcode/common/BC_CommonBitMatrix.h" +#include "xfa/fxbarcode/datamatrix/BC_C40Encoder.h" +#include "xfa/fxbarcode/datamatrix/BC_Encoder.h" +#include "xfa/fxbarcode/datamatrix/BC_EncoderContext.h" +#include "xfa/fxbarcode/datamatrix/BC_HighLevelEncoder.h" +#include "xfa/fxbarcode/datamatrix/BC_SymbolInfo.h" +#include "xfa/fxbarcode/datamatrix/BC_SymbolShapeHint.h" +#include "xfa/fxbarcode/datamatrix/BC_TextEncoder.h" + +CBC_TextEncoder::CBC_TextEncoder() {} +CBC_TextEncoder::~CBC_TextEncoder() {} +int32_t CBC_TextEncoder::getEncodingMode() { + return TEXT_ENCODATION; +} +int32_t CBC_TextEncoder::encodeChar(FX_WCHAR c, + CFX_WideString& sb, + int32_t& e) { + if (c == ' ') { + sb += (FX_WCHAR)'\3'; + return 1; + } + if (c >= '0' && c <= '9') { + sb += (FX_WCHAR)(c - 48 + 4); + return 1; + } + if (c >= 'a' && c <= 'z') { + sb += (FX_WCHAR)(c - 97 + 14); + return 1; + } + if (c <= 0x1f) { + sb += (FX_WCHAR)'\0'; + sb += c; + return 2; + } + if (c >= '!' && c <= '/') { + sb += (FX_WCHAR)'\1'; + sb += (FX_WCHAR)(c - 33); + return 2; + } + if (c >= ':' && c <= '@') { + sb += (FX_WCHAR)'\1'; + sb += (FX_WCHAR)(c - 58 + 15); + return 2; + } + if (c >= '[' && c <= '_') { + sb += (FX_WCHAR)'\1'; + sb += (FX_WCHAR)(c - 91 + 22); + return 2; + } + if (c == 0x0060) { + sb += (FX_WCHAR)'\2'; + sb += (FX_WCHAR)(c - 96); + return 2; + } + if (c >= 'A' && c <= 'Z') { + sb += (FX_WCHAR)'\2'; + sb += (FX_WCHAR)(c - 65 + 1); + return 2; + } + if (c >= '{' && c <= 0x007f) { + sb += (FX_WCHAR)'\2'; + sb += (FX_WCHAR)(c - 123 + 27); + return 2; + } + if (c >= 0x0080) { + sb += (FX_WCHAR)'\1'; + sb += (FX_WCHAR)0x001e; + int32_t len = 2; + len += encodeChar((FX_WCHAR)(c - 128), sb, e); + BC_EXCEPTION_CHECK_ReturnValue(e, -1); + return len; + } + CBC_HighLevelEncoder::illegalCharacter(c, e); + return -1; +} diff --git a/xfa/fxbarcode/datamatrix/BC_TextEncoder.h b/xfa/fxbarcode/datamatrix/BC_TextEncoder.h new file mode 100644 index 0000000000..1f97f3f8c6 --- /dev/null +++ b/xfa/fxbarcode/datamatrix/BC_TextEncoder.h @@ -0,0 +1,19 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef XFA_FXBARCODE_DATAMATRIX_BC_TEXTENCODER_H_ +#define XFA_FXBARCODE_DATAMATRIX_BC_TEXTENCODER_H_ + +class CBC_TextEncoder; +class CBC_TextEncoder : public CBC_C40Encoder { + public: + CBC_TextEncoder(); + virtual ~CBC_TextEncoder(); + int32_t getEncodingMode(); + int32_t encodeChar(FX_WCHAR c, CFX_WideString& sb, int32_t& e); +}; + +#endif // XFA_FXBARCODE_DATAMATRIX_BC_TEXTENCODER_H_ diff --git a/xfa/fxbarcode/datamatrix/BC_X12Encoder.cpp b/xfa/fxbarcode/datamatrix/BC_X12Encoder.cpp new file mode 100644 index 0000000000..9ebfc46700 --- /dev/null +++ b/xfa/fxbarcode/datamatrix/BC_X12Encoder.cpp @@ -0,0 +1,100 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com +// Original code is licensed as follows: +/* + * Copyright 2006-2007 Jeremias Maerki. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "xfa/fxbarcode/BC_Dimension.h" +#include "xfa/fxbarcode/common/BC_CommonBitMatrix.h" +#include "xfa/fxbarcode/datamatrix/BC_C40Encoder.h" +#include "xfa/fxbarcode/datamatrix/BC_Encoder.h" +#include "xfa/fxbarcode/datamatrix/BC_EncoderContext.h" +#include "xfa/fxbarcode/datamatrix/BC_HighLevelEncoder.h" +#include "xfa/fxbarcode/datamatrix/BC_SymbolInfo.h" +#include "xfa/fxbarcode/datamatrix/BC_SymbolShapeHint.h" +#include "xfa/fxbarcode/datamatrix/BC_X12Encoder.h" + +CBC_X12Encoder::CBC_X12Encoder() {} +CBC_X12Encoder::~CBC_X12Encoder() {} +int32_t CBC_X12Encoder::getEncodingMode() { + return X12_ENCODATION; +} +void CBC_X12Encoder::Encode(CBC_EncoderContext& context, int32_t& e) { + CFX_WideString buffer; + while (context.hasMoreCharacters()) { + FX_WCHAR c = context.getCurrentChar(); + context.m_pos++; + encodeChar(c, buffer, e); + if (e != BCExceptionNO) { + return; + } + int32_t count = buffer.GetLength(); + if ((count % 3) == 0) { + writeNextTriplet(context, buffer); + int32_t newMode = CBC_HighLevelEncoder::lookAheadTest( + context.m_msg, context.m_pos, getEncodingMode()); + if (newMode != getEncodingMode()) { + context.signalEncoderChange(newMode); + break; + } + } + } + handleEOD(context, buffer, e); +} +void CBC_X12Encoder::handleEOD(CBC_EncoderContext& context, + CFX_WideString& buffer, + int32_t& e) { + context.updateSymbolInfo(e); + if (e != BCExceptionNO) { + return; + } + int32_t available = + context.m_symbolInfo->m_dataCapacity - context.getCodewordCount(); + int32_t count = buffer.GetLength(); + if (count == 2) { + context.writeCodeword(CBC_HighLevelEncoder::X12_UNLATCH); + context.m_pos -= 2; + context.signalEncoderChange(ASCII_ENCODATION); + } else if (count == 1) { + context.m_pos--; + if (available > 1) { + context.writeCodeword(CBC_HighLevelEncoder::X12_UNLATCH); + } + context.signalEncoderChange(ASCII_ENCODATION); + } +} +int32_t CBC_X12Encoder::encodeChar(FX_WCHAR c, CFX_WideString& sb, int32_t& e) { + if (c == '\r') { + sb += (FX_WCHAR)'\0'; + } else if (c == '*') { + sb += (FX_WCHAR)'\1'; + } else if (c == '>') { + sb += (FX_WCHAR)'\2'; + } else if (c == ' ') { + sb += (FX_WCHAR)'\3'; + } else if (c >= '0' && c <= '9') { + sb += (FX_WCHAR)(c - 48 + 4); + } else if (c >= 'A' && c <= 'Z') { + sb += (FX_WCHAR)(c - 65 + 14); + } else { + CBC_HighLevelEncoder::illegalCharacter(c, e); + BC_EXCEPTION_CHECK_ReturnValue(e, -1); + } + return 1; +} diff --git a/xfa/fxbarcode/datamatrix/BC_X12Encoder.h b/xfa/fxbarcode/datamatrix/BC_X12Encoder.h new file mode 100644 index 0000000000..5dccbb1d6f --- /dev/null +++ b/xfa/fxbarcode/datamatrix/BC_X12Encoder.h @@ -0,0 +1,24 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef XFA_FXBARCODE_DATAMATRIX_BC_X12ENCODER_H_ +#define XFA_FXBARCODE_DATAMATRIX_BC_X12ENCODER_H_ + +class CBC_C40Encoder; +class CBC_X12Encoder; +class CBC_X12Encoder : public CBC_C40Encoder { + public: + CBC_X12Encoder(); + virtual ~CBC_X12Encoder(); + int32_t getEncodingMode(); + void Encode(CBC_EncoderContext& context, int32_t& e); + void handleEOD(CBC_EncoderContext& context, + CFX_WideString& buffer, + int32_t& e); + int32_t encodeChar(FX_WCHAR c, CFX_WideString& sb, int32_t& e); +}; + +#endif // XFA_FXBARCODE_DATAMATRIX_BC_X12ENCODER_H_ diff --git a/xfa/fxbarcode/oned/BC_OneDReader.cpp b/xfa/fxbarcode/oned/BC_OneDReader.cpp new file mode 100644 index 0000000000..c66ec0bebd --- /dev/null +++ b/xfa/fxbarcode/oned/BC_OneDReader.cpp @@ -0,0 +1,175 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com +// Original code is licensed as follows: +/* + * Copyright 2008 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <algorithm> +#include <memory> + +#include "xfa/fxbarcode/BC_BinaryBitmap.h" +#include "xfa/fxbarcode/BC_Reader.h" +#include "xfa/fxbarcode/common/BC_CommonBitArray.h" +#include "xfa/fxbarcode/oned/BC_OneDReader.h" +#include "xfa/fxbarcode/utils.h" + +CBC_OneDReader::CBC_OneDReader() {} +CBC_OneDReader::~CBC_OneDReader() {} +CFX_ByteString CBC_OneDReader::Decode(CBC_BinaryBitmap* image, int32_t& e) { + CFX_ByteString strtemp = Decode(image, 0, e); + BC_EXCEPTION_CHECK_ReturnValue(e, ""); + return strtemp; +} +CFX_ByteString CBC_OneDReader::Decode(CBC_BinaryBitmap* image, + int32_t hints, + int32_t& e) { + CFX_ByteString strtemp = DeDecode(image, hints, e); + BC_EXCEPTION_CHECK_ReturnValue(e, ""); + return strtemp; +} +CFX_ByteString CBC_OneDReader::DeDecode(CBC_BinaryBitmap* image, + int32_t hints, + int32_t& e) { + int32_t height = image->GetHeight(); + int32_t middle = height >> 1; + FX_BOOL tryHarder = FALSE; + int32_t rowStep = std::max(1, height >> (tryHarder ? 8 : 5)); + int32_t maxLines; + if (tryHarder) { + maxLines = height; + } else { + maxLines = 15; + } + for (int32_t x = 0; x < maxLines; x++) { + int32_t rowStepsAboveOrBelow = (x + 1) >> 1; + const bool isAbove = (x & 0x01) == 0; + int32_t rowNumber = + middle + + rowStep * (isAbove ? rowStepsAboveOrBelow : -rowStepsAboveOrBelow); + if (rowNumber < 0 || rowNumber >= height) { + break; + } + std::unique_ptr<CBC_CommonBitArray> row( + image->GetBlackRow(rowNumber, nullptr, e)); + if (e != BCExceptionNO) { + e = BCExceptionNO; + continue; + } + for (int32_t attempt = 0; attempt < 2; attempt++) { + if (attempt == 1) { + row->Reverse(); + } + CFX_ByteString result = DecodeRow(rowNumber, row.get(), hints, e); + if (e != BCExceptionNO) { + e = BCExceptionNO; + continue; + } + return result; + } + } + e = BCExceptionNotFound; + return ""; +} +void CBC_OneDReader::RecordPattern(CBC_CommonBitArray* row, + int32_t start, + CFX_Int32Array* counters, + int32_t& e) { + int32_t numCounters = counters->GetSize(); + for (int32_t i = 0; i < numCounters; i++) { + (*counters)[i] = 0; + } + int32_t end = row->GetSize(); + if (start >= end) { + e = BCExceptionNotFound; + return; + } + FX_BOOL isWhite = !row->Get(start); + int32_t counterPosition = 0; + int32_t j = start; + while (j < end) { + FX_BOOL pixel = row->Get(j); + if (pixel ^ isWhite) { + (*counters)[counterPosition]++; + } else { + counterPosition++; + if (counterPosition == numCounters) { + break; + } else { + (*counters)[counterPosition] = 1; + isWhite = !isWhite; + } + } + j++; + } + if (!(counterPosition == numCounters || + (counterPosition == numCounters - 1 && j == end))) { + e = BCExceptionNotFound; + return; + } +} +void CBC_OneDReader::RecordPatternInReverse(CBC_CommonBitArray* row, + int32_t start, + CFX_Int32Array* counters, + int32_t& e) { + int32_t numTransitionsLeft = counters->GetSize(); + FX_BOOL last = row->Get(start); + while (start > 0 && numTransitionsLeft >= 0) { + if (row->Get(--start) != last) { + numTransitionsLeft--; + last = !last; + } + } + if (numTransitionsLeft >= 0) { + e = BCExceptionNotFound; + return; + } + RecordPattern(row, start + 1, counters, e); + BC_EXCEPTION_CHECK_ReturnVoid(e); +} +int32_t CBC_OneDReader::PatternMatchVariance(CFX_Int32Array* counters, + const int32_t* pattern, + int32_t maxIndividualVariance) { + int32_t numCounters = counters->GetSize(); + int32_t total = 0; + int32_t patternLength = 0; + for (int32_t i = 0; i < numCounters; i++) { + total += (*counters)[i]; + patternLength += pattern[i]; + } + if (total < patternLength) { +#undef max + return FXSYS_IntMax; + } + int32_t unitBarWidth = (total << INTEGER_MATH_SHIFT) / patternLength; + maxIndividualVariance = + (maxIndividualVariance * unitBarWidth) >> INTEGER_MATH_SHIFT; + int32_t totalVariance = 0; + for (int32_t x = 0; x < numCounters; x++) { + int32_t counter = (*counters)[x] << INTEGER_MATH_SHIFT; + int32_t scaledPattern = pattern[x] * unitBarWidth; + int32_t variance = counter > scaledPattern ? counter - scaledPattern + : scaledPattern - counter; + if (variance > maxIndividualVariance) { +#undef max + return FXSYS_IntMax; + } + totalVariance += variance; + } + return totalVariance / total; +} diff --git a/xfa/fxbarcode/oned/BC_OneDReader.h b/xfa/fxbarcode/oned/BC_OneDReader.h new file mode 100644 index 0000000000..2bab06e9b8 --- /dev/null +++ b/xfa/fxbarcode/oned/BC_OneDReader.h @@ -0,0 +1,50 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef XFA_FXBARCODE_ONED_BC_ONEDREADER_H_ +#define XFA_FXBARCODE_ONED_BC_ONEDREADER_H_ + +#include "xfa/fxbarcode/BC_Reader.h" + +class CBC_BinaryBitmap; +class CBC_CommonBitArray; + +class CBC_OneDReader : public CBC_Reader { + public: + CBC_OneDReader(); + virtual ~CBC_OneDReader(); + virtual CFX_ByteString Decode(CBC_BinaryBitmap* image, int32_t& e); + virtual CFX_ByteString Decode(CBC_BinaryBitmap* image, + int32_t hints, + int32_t& e); + virtual CFX_ByteString DecodeRow(int32_t rowNumber, + CBC_CommonBitArray* row, + int32_t hints, + int32_t& e) { + return ""; + } + + private: + CFX_ByteString DeDecode(CBC_BinaryBitmap* image, int32_t hints, int32_t& e); + + protected: + static const int32_t INTEGER_MATH_SHIFT = 8; + static const int32_t PATTERN_MATCH_RESULT_SCALE_FACTOR = 1 << 8; + + void RecordPattern(CBC_CommonBitArray* row, + int32_t start, + CFX_Int32Array* counters, + int32_t& e); + void RecordPatternInReverse(CBC_CommonBitArray* row, + int32_t start, + CFX_Int32Array* counters, + int32_t& e); + int32_t PatternMatchVariance(CFX_Int32Array* counters, + const int32_t* pattern, + int32_t maxIndividualVariance); +}; + +#endif // XFA_FXBARCODE_ONED_BC_ONEDREADER_H_ diff --git a/xfa/fxbarcode/oned/BC_OneDimReader.cpp b/xfa/fxbarcode/oned/BC_OneDimReader.cpp new file mode 100644 index 0000000000..5187c34af9 --- /dev/null +++ b/xfa/fxbarcode/oned/BC_OneDimReader.cpp @@ -0,0 +1,219 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com +// Original code is licensed as follows: +/* + * Copyright 2008 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "xfa/fxbarcode/oned/BC_OneDimReader.h" + +#include <memory> + +#include "xfa/fxbarcode/BC_Reader.h" +#include "xfa/fxbarcode/common/BC_CommonBitArray.h" +#include "xfa/fxbarcode/oned/BC_OneDReader.h" +#include "xfa/fxbarcode/utils.h" + +const int32_t CBC_OneDimReader::START_END_PATTERN[3] = {1, 1, 1}; +const int32_t CBC_OneDimReader::MIDDLE_PATTERN[5] = {1, 1, 1, 1, 1}; +const int32_t CBC_OneDimReader::L_PATTERNS[10][4] = { + {3, 2, 1, 1}, {2, 2, 2, 1}, {2, 1, 2, 2}, {1, 4, 1, 1}, {1, 1, 3, 2}, + {1, 2, 3, 1}, {1, 1, 1, 4}, {1, 3, 1, 2}, {1, 2, 1, 3}, {3, 1, 1, 2}}; +const int32_t CBC_OneDimReader::L_AND_G_PATTERNS[20][4] = { + {3, 2, 1, 1}, {2, 2, 2, 1}, {2, 1, 2, 2}, {1, 4, 1, 1}, {1, 1, 3, 2}, + {1, 2, 3, 1}, {1, 1, 1, 4}, {1, 3, 1, 2}, {1, 2, 1, 3}, {3, 1, 1, 2}, + {1, 1, 2, 3}, {1, 2, 2, 2}, {2, 2, 1, 2}, {1, 1, 4, 1}, {2, 3, 1, 1}, + {1, 3, 2, 1}, {4, 1, 1, 1}, {2, 1, 3, 1}, {3, 1, 2, 1}, {2, 1, 1, 3}}; + +CBC_OneDimReader::CBC_OneDimReader() {} +CBC_OneDimReader::~CBC_OneDimReader() {} +CFX_Int32Array* CBC_OneDimReader::FindStartGuardPattern(CBC_CommonBitArray* row, + int32_t& e) { + FX_BOOL foundStart = FALSE; + CFX_Int32Array* startRange = NULL; + CFX_Int32Array startEndPattern; + startEndPattern.SetSize(3); + startEndPattern[0] = START_END_PATTERN[0]; + startEndPattern[1] = START_END_PATTERN[1]; + startEndPattern[2] = START_END_PATTERN[2]; + int32_t nextStart = 0; + while (!foundStart) { + delete startRange; + startRange = FindGuardPattern(row, nextStart, FALSE, &startEndPattern, e); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + int32_t start = (*startRange)[0]; + nextStart = (*startRange)[1]; + if (start <= 1) { + break; + } + int32_t quietStart = start - (nextStart - start); + if (quietStart >= 0) { + FX_BOOL booT = row->IsRange(quietStart, start, FALSE, e); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + foundStart = booT; + } + } + return startRange; +} +CFX_ByteString CBC_OneDimReader::DecodeRow(int32_t rowNumber, + CBC_CommonBitArray* row, + int32_t hints, + int32_t& e) { + std::unique_ptr<CFX_Int32Array> result(FindStartGuardPattern(row, e)); + BC_EXCEPTION_CHECK_ReturnValue(e, ""); + CFX_ByteString temp = DecodeRow(rowNumber, row, result.get(), hints, e); + BC_EXCEPTION_CHECK_ReturnValue(e, ""); + return temp; +} +CFX_ByteString CBC_OneDimReader::DecodeRow(int32_t rowNumber, + CBC_CommonBitArray* row, + CFX_Int32Array* startGuardRange, + int32_t hints, + int32_t& e) { + CFX_ByteString result; + DecodeMiddle(row, startGuardRange, result, e); + BC_EXCEPTION_CHECK_ReturnValue(e, ""); + FX_BOOL b = CheckChecksum(result, e); + BC_EXCEPTION_CHECK_ReturnValue(e, ""); + if (!b) { + e = BCExceptionChecksumException; + return ""; + } + return result; +} +FX_BOOL CBC_OneDimReader::CheckChecksum(CFX_ByteString& s, int32_t& e) { + FX_BOOL temp = CheckStandardUPCEANChecksum(s, e); + BC_EXCEPTION_CHECK_ReturnValue(e, FALSE); + return temp; +} +FX_BOOL CBC_OneDimReader::CheckStandardUPCEANChecksum(CFX_ByteString& s, + int32_t& e) { + int32_t length = s.GetLength(); + if (length == 0) { + return FALSE; + } + int32_t sum = 0; + for (int32_t i = length - 2; i >= 0; i -= 2) { + int32_t digit = (int32_t)s[i] - (int32_t)'0'; + if (digit < 0 || digit > 9) { + e = BCExceptionFormatException; + return FALSE; + } + sum += digit; + } + sum *= 3; + for (int32_t j = length - 1; j >= 0; j -= 2) { + int32_t digit = (int32_t)s[j] - (int32_t)'0'; + if (digit < 0 || digit > 9) { + e = BCExceptionFormatException; + return FALSE; + } + sum += digit; + } + return sum % 10 == 0; +} +CFX_Int32Array* CBC_OneDimReader::DecodeEnd(CBC_CommonBitArray* row, + int32_t endStart, + int32_t& e) { + CFX_Int32Array startEndPattern; + startEndPattern.Add(START_END_PATTERN[0]); + startEndPattern.Add(START_END_PATTERN[1]); + startEndPattern.Add(START_END_PATTERN[2]); + CFX_Int32Array* FindGuard = + FindGuardPattern(row, endStart, FALSE, &startEndPattern, e); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + return FindGuard; +} +CFX_Int32Array* CBC_OneDimReader::FindGuardPattern(CBC_CommonBitArray* row, + int32_t rowOffset, + FX_BOOL whiteFirst, + CFX_Int32Array* pattern, + int32_t& e) { + int32_t patternLength = pattern->GetSize(); + CFX_Int32Array counters; + counters.SetSize(patternLength); + int32_t width = row->GetSize(); + FX_BOOL isWhite = FALSE; + while (rowOffset < width) { + isWhite = !row->Get(rowOffset); + if (whiteFirst == isWhite) { + break; + } + rowOffset++; + } + int32_t counterPosition = 0; + int32_t patternStart = rowOffset; + for (int32_t x = rowOffset; x < width; x++) { + FX_BOOL pixel = row->Get(x); + if (pixel ^ isWhite) { + counters[counterPosition]++; + } else { + if (counterPosition == patternLength - 1) { + if (PatternMatchVariance(&counters, &(*pattern)[0], + MAX_INDIVIDUAL_VARIANCE) < MAX_AVG_VARIANCE) { + CFX_Int32Array* result = new CFX_Int32Array(); + result->SetSize(2); + (*result)[0] = patternStart; + (*result)[1] = x; + return result; + } + patternStart += counters[0] + counters[1]; + for (int32_t y = 2; y < patternLength; y++) { + counters[y - 2] = counters[y]; + } + counters[patternLength - 2] = 0; + counters[patternLength - 1] = 0; + counterPosition--; + } else { + counterPosition++; + } + counters[counterPosition] = 1; + isWhite = !isWhite; + } + } + e = BCExceptionNotFound; + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + return NULL; +} +int32_t CBC_OneDimReader::DecodeDigit(CBC_CommonBitArray* row, + CFX_Int32Array* counters, + int32_t rowOffset, + const int32_t* patterns, + int32_t patternLength, + int32_t& e) { + RecordPattern(row, rowOffset, counters, e); + BC_EXCEPTION_CHECK_ReturnValue(e, 0); + int32_t bestVariance = MAX_AVG_VARIANCE; + int32_t bestMatch = -1; + int32_t max = patternLength; + for (int32_t i = 0; i < max; i++) { + int32_t variance = PatternMatchVariance(counters, &patterns[i * 4], + MAX_INDIVIDUAL_VARIANCE); + if (variance < bestVariance) { + bestVariance = variance; + bestMatch = i; + } + } + if (bestMatch >= 0) { + return bestMatch; + } else { + e = BCExceptionNotFound; + return 0; + } + return 0; +} diff --git a/xfa/fxbarcode/oned/BC_OneDimReader.h b/xfa/fxbarcode/oned/BC_OneDimReader.h new file mode 100644 index 0000000000..cc84ffd39a --- /dev/null +++ b/xfa/fxbarcode/oned/BC_OneDimReader.h @@ -0,0 +1,66 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef XFA_FXBARCODE_ONED_BC_ONEDIMREADER_H_ +#define XFA_FXBARCODE_ONED_BC_ONEDIMREADER_H_ + +#include "core/include/fxcrt/fx_basic.h" +#include "xfa/fxbarcode/oned/BC_OneDReader.h" + +class CBC_CommonBitArray; + +class CBC_OneDimReader : public CBC_OneDReader { + private: + static const int32_t MAX_AVG_VARIANCE = (int32_t)(256 * 0.48f); + static const int32_t MAX_INDIVIDUAL_VARIANCE = (int32_t)(256 * 0.7f); + + FX_BOOL CheckStandardUPCEANChecksum(CFX_ByteString& s, int32_t& e); + + public: + static const int32_t START_END_PATTERN[3]; + static const int32_t MIDDLE_PATTERN[5]; + static const int32_t L_PATTERNS[10][4]; + static const int32_t L_AND_G_PATTERNS[20][4]; + + CBC_OneDimReader(); + virtual ~CBC_OneDimReader(); + + CFX_ByteString DecodeRow(int32_t rowNumber, + CBC_CommonBitArray* row, + int32_t hints, + int32_t& e); + CFX_ByteString DecodeRow(int32_t rowNumber, + CBC_CommonBitArray* row, + CFX_Int32Array* startGuardRange, + int32_t hints, + int32_t& e); + + protected: + CFX_Int32Array* FindStartGuardPattern(CBC_CommonBitArray* row, int32_t& e); + virtual FX_BOOL CheckChecksum(CFX_ByteString& s, int32_t& e); + CFX_Int32Array* FindGuardPattern(CBC_CommonBitArray* row, + int32_t rowOffset, + FX_BOOL whiteFirst, + CFX_Int32Array* pattern, + int32_t& e); + int32_t DecodeDigit(CBC_CommonBitArray* row, + CFX_Int32Array* counters, + int32_t rowOffset, + const int32_t* patterns, + int32_t patternLength, + int32_t& e); + virtual int32_t DecodeMiddle(CBC_CommonBitArray* row, + CFX_Int32Array* startRange, + CFX_ByteString& resultResult, + int32_t& e) { + return 0; + } + virtual CFX_Int32Array* DecodeEnd(CBC_CommonBitArray* row, + int32_t endStart, + int32_t& e); +}; + +#endif // XFA_FXBARCODE_ONED_BC_ONEDIMREADER_H_ diff --git a/xfa/fxbarcode/oned/BC_OneDimWriter.cpp b/xfa/fxbarcode/oned/BC_OneDimWriter.cpp new file mode 100644 index 0000000000..62ca97f488 --- /dev/null +++ b/xfa/fxbarcode/oned/BC_OneDimWriter.cpp @@ -0,0 +1,437 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com +// Original code is licensed as follows: +/* + * Copyright 2011 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "xfa/fxbarcode/oned/BC_OneDimWriter.h" + +#include <algorithm> +#include <memory> + +#include "xfa/fxbarcode/BC_Writer.h" +#include "xfa/fxbarcode/common/BC_CommonBitMatrix.h" + +CBC_OneDimWriter::CBC_OneDimWriter() { + m_locTextLoc = BC_TEXT_LOC_BELOWEMBED; + m_bPrintChecksum = TRUE; + m_iDataLenth = 0; + m_bCalcChecksum = FALSE; + m_pFont = NULL; + m_fFontSize = 10; + m_iFontStyle = 0; + m_fontColor = 0xff000000; + m_iContentLen = 0; + m_bLeftPadding = FALSE; + m_bRightPadding = FALSE; + m_output = NULL; +} +CBC_OneDimWriter::~CBC_OneDimWriter() { + delete m_output; +} +void CBC_OneDimWriter::SetPrintChecksum(FX_BOOL checksum) { + m_bPrintChecksum = checksum; +} +void CBC_OneDimWriter::SetDataLength(int32_t length) { + m_iDataLenth = length; +} +void CBC_OneDimWriter::SetCalcChecksum(int32_t state) { + m_bCalcChecksum = state; +} +FX_BOOL CBC_OneDimWriter::SetFont(CFX_Font* cFont) { + if (cFont == NULL) { + return FALSE; + } + m_pFont = cFont; + return TRUE; +} +void CBC_OneDimWriter::SetFontSize(FX_FLOAT size) { + m_fFontSize = size; +} +void CBC_OneDimWriter::SetFontStyle(int32_t style) { + m_iFontStyle = style; +} +void CBC_OneDimWriter::SetFontColor(FX_ARGB color) { + m_fontColor = color; +} +FX_WCHAR CBC_OneDimWriter::Upper(FX_WCHAR ch) { + if (ch >= 'a' && ch <= 'z') { + ch = ch - ('a' - 'A'); + } + return ch; +} +uint8_t* CBC_OneDimWriter::Encode(const CFX_ByteString& contents, + BCFORMAT format, + int32_t& outWidth, + int32_t& outHeight, + int32_t hints, + int32_t& e) { + uint8_t* ret = NULL; + outHeight = 1; + if (m_Width >= 20) { + ret = Encode(contents, outWidth, e); + } else { + ret = Encode(contents, outWidth, e); + } + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + return ret; +} +uint8_t* CBC_OneDimWriter::Encode(const CFX_ByteString& contents, + BCFORMAT format, + int32_t& outWidth, + int32_t& outHeight, + int32_t& e) { + uint8_t* ret = Encode(contents, format, outWidth, outHeight, 0, e); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + return ret; +} +int32_t CBC_OneDimWriter::AppendPattern(uint8_t* target, + int32_t pos, + const int32_t* pattern, + int32_t patternLength, + int32_t startColor, + int32_t& e) { + if (startColor != 0 && startColor != 1) { + e = BCExceptionValueMustBeEither0or1; + return 0; + } + uint8_t color = (uint8_t)startColor; + int32_t numAdded = 0; + for (int32_t i = 0; i < patternLength; i++) { + for (int32_t j = 0; j < pattern[i]; j++) { + target[pos] = color; + pos += 1; + numAdded += 1; + } + color ^= 1; + } + return numAdded; +} +void CBC_OneDimWriter::CalcTextInfo(const CFX_ByteString& text, + FXTEXT_CHARPOS* charPos, + CFX_Font* cFont, + FX_FLOAT geWidth, + int32_t fontSize, + FX_FLOAT& charsLen) { + std::unique_ptr<CFX_UnicodeEncodingEx> encoding( + FX_CreateFontEncodingEx(cFont)); + + int32_t length = text.GetLength(); + FX_DWORD* pCharCode = FX_Alloc(FX_DWORD, text.GetLength()); + FX_FLOAT charWidth = 0; + for (int32_t j = 0; j < text.GetLength(); j++) { + pCharCode[j] = encoding->CharCodeFromUnicode(text[j]); + int32_t glyp_code = encoding->GlyphFromCharCode(pCharCode[j]); + int32_t glyp_value = cFont->GetGlyphWidth(glyp_code); + FX_FLOAT temp = (FX_FLOAT)((glyp_value)*fontSize / 1000.0); + charWidth += temp; + } + charsLen = charWidth; + FX_FLOAT leftPositon = (FX_FLOAT)(geWidth - charsLen) / 2.0f; + if (leftPositon < 0 && geWidth == 0) { + leftPositon = 0; + } + FX_FLOAT penX = 0.0; + FX_FLOAT penY = + (FX_FLOAT)FXSYS_abs(cFont->GetDescent()) * (FX_FLOAT)fontSize / 1000.0f; + FX_FLOAT left = leftPositon; + FX_FLOAT top = 0.0; + charPos[0].m_OriginX = penX + left; + charPos[0].m_OriginY = penY + top; + charPos[0].m_GlyphIndex = encoding->GlyphFromCharCode(pCharCode[0]); + charPos[0].m_FontCharWidth = cFont->GetGlyphWidth(charPos[0].m_GlyphIndex); +#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ + charPos[0].m_ExtGID = charPos[0].m_GlyphIndex; +#endif + penX += (FX_FLOAT)(charPos[0].m_FontCharWidth) * (FX_FLOAT)fontSize / 1000.0f; + for (int32_t i = 1; i < length; i++) { + charPos[i].m_OriginX = penX + left; + charPos[i].m_OriginY = penY + top; + charPos[i].m_GlyphIndex = encoding->GlyphFromCharCode(pCharCode[i]); + charPos[i].m_FontCharWidth = cFont->GetGlyphWidth(charPos[i].m_GlyphIndex); +#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ + charPos[i].m_ExtGID = charPos[i].m_GlyphIndex; +#endif + penX += + (FX_FLOAT)(charPos[i].m_FontCharWidth) * (FX_FLOAT)fontSize / 1000.0f; + } + FX_Free(pCharCode); +} +void CBC_OneDimWriter::ShowDeviceChars(CFX_RenderDevice* device, + const CFX_Matrix* matrix, + const CFX_ByteString str, + FX_FLOAT geWidth, + FXTEXT_CHARPOS* pCharPos, + FX_FLOAT locX, + FX_FLOAT locY, + int32_t barWidth) { + int32_t iFontSize = (int32_t)fabs(m_fFontSize); + int32_t iTextHeight = iFontSize + 1; + CFX_FloatRect rect((FX_FLOAT)locX, (FX_FLOAT)locY, (FX_FLOAT)(locX + geWidth), + (FX_FLOAT)(locY + iTextHeight)); + if (geWidth != m_Width) { + rect.right -= 1; + } + matrix->TransformRect(rect); + FX_RECT re = rect.GetOutterRect(); + device->FillRect(&re, m_backgroundColor); + CFX_Matrix affine_matrix(1.0, 0.0, 0.0, -1.0, (FX_FLOAT)locX, + (FX_FLOAT)(locY + iFontSize)); + if (matrix) { + affine_matrix.Concat(*matrix); + } + device->DrawNormalText(str.GetLength(), pCharPos, m_pFont, + CFX_GEModule::Get()->GetFontCache(), + (FX_FLOAT)iFontSize, (CFX_Matrix*)&affine_matrix, + m_fontColor, FXTEXT_CLEARTYPE); +} +void CBC_OneDimWriter::ShowBitmapChars(CFX_DIBitmap* pOutBitmap, + const CFX_ByteString str, + FX_FLOAT geWidth, + FXTEXT_CHARPOS* pCharPos, + FX_FLOAT locX, + FX_FLOAT locY, + int32_t barWidth) { + int32_t iFontSize = (int32_t)fabs(m_fFontSize); + int32_t iTextHeight = iFontSize + 1; + CFX_FxgeDevice ge; + ge.Create((int)geWidth, iTextHeight, m_colorSpace); + FX_RECT geRect(0, 0, (int)geWidth, iTextHeight); + ge.FillRect(&geRect, m_backgroundColor); + CFX_Matrix affine_matrix(1.0, 0.0, 0.0, -1.0, 0.0, (FX_FLOAT)iFontSize); + ge.DrawNormalText(str.GetLength(), pCharPos, m_pFont, + CFX_GEModule::Get()->GetFontCache(), (FX_FLOAT)iFontSize, + (CFX_Matrix*)&affine_matrix, m_fontColor, FXTEXT_CLEARTYPE); + CFX_FxgeDevice geBitmap; + geBitmap.Attach(pOutBitmap); + geBitmap.SetDIBits(ge.GetBitmap(), (int)locX, (int)locY); +} +void CBC_OneDimWriter::ShowChars(const CFX_WideStringC& contents, + CFX_DIBitmap* pOutBitmap, + CFX_RenderDevice* device, + const CFX_Matrix* matrix, + int32_t barWidth, + int32_t multiple, + int32_t& e) { + if (device == NULL && pOutBitmap == NULL) { + e = BCExceptionIllegalArgument; + return; + } + if (m_pFont == NULL) { + e = BCExceptionNullPointer; + return; + } + CFX_ByteString str = FX_UTF8Encode(contents); + int32_t iLen = str.GetLength(); + FXTEXT_CHARPOS* pCharPos = FX_Alloc(FXTEXT_CHARPOS, iLen); + FXSYS_memset(pCharPos, 0, sizeof(FXTEXT_CHARPOS) * iLen); + FX_FLOAT charsLen = 0; + FX_FLOAT geWidth = 0; + if (m_locTextLoc == BC_TEXT_LOC_ABOVEEMBED || + m_locTextLoc == BC_TEXT_LOC_BELOWEMBED) { + geWidth = 0; + } else if (m_locTextLoc == BC_TEXT_LOC_ABOVE || + m_locTextLoc == BC_TEXT_LOC_BELOW) { + geWidth = (FX_FLOAT)barWidth; + } + int32_t iFontSize = (int32_t)fabs(m_fFontSize); + int32_t iTextHeight = iFontSize + 1; + CalcTextInfo(str, pCharPos, m_pFont, geWidth, iFontSize, charsLen); + if (charsLen < 1) { + return; + } + int32_t locX = 0; + int32_t locY = 0; + switch (m_locTextLoc) { + case BC_TEXT_LOC_ABOVEEMBED: + locX = (int32_t)(barWidth - charsLen) / 2; + locY = 0; + geWidth = charsLen; + break; + case BC_TEXT_LOC_ABOVE: + locX = 0; + locY = 0; + geWidth = (FX_FLOAT)barWidth; + break; + case BC_TEXT_LOC_BELOWEMBED: + locX = (int32_t)(barWidth - charsLen) / 2; + locY = m_Height - iTextHeight; + geWidth = charsLen; + break; + case BC_TEXT_LOC_BELOW: + default: + locX = 0; + locY = m_Height - iTextHeight; + geWidth = (FX_FLOAT)barWidth; + break; + } + if (device) { + ShowDeviceChars(device, matrix, str, geWidth, pCharPos, (FX_FLOAT)locX, + (FX_FLOAT)locY, barWidth); + } else { + ShowBitmapChars(pOutBitmap, str, geWidth, pCharPos, (FX_FLOAT)locX, + (FX_FLOAT)locY, barWidth); + } + FX_Free(pCharPos); +} +void CBC_OneDimWriter::RenderBitmapResult(CFX_DIBitmap*& pOutBitmap, + const CFX_WideStringC& contents, + int32_t& e) { + if (m_output == NULL) { + BC_EXCEPTION_CHECK_ReturnVoid(e); + } + pOutBitmap = CreateDIBitmap(m_output->GetWidth(), m_output->GetHeight()); + pOutBitmap->Clear(m_backgroundColor); + if (!pOutBitmap) { + e = BCExceptionFailToCreateBitmap; + return; + } + for (int32_t x = 0; x < m_output->GetWidth(); x++) { + for (int32_t y = 0; y < m_output->GetHeight(); y++) { + if (m_output->Get(x, y)) { + pOutBitmap->SetPixel(x, y, m_barColor); + } + } + } + int32_t i = 0; + for (; i < contents.GetLength(); i++) + if (contents.GetAt(i) != ' ') { + break; + } + if (m_locTextLoc != BC_TEXT_LOC_NONE && i < contents.GetLength()) { + ShowChars(contents, pOutBitmap, NULL, NULL, m_barWidth, m_multiple, e); + BC_EXCEPTION_CHECK_ReturnVoid(e); + } + CFX_DIBitmap* pStretchBitmap = pOutBitmap->StretchTo(m_Width, m_Height); + if (pOutBitmap) { + delete pOutBitmap; + } + pOutBitmap = pStretchBitmap; +} +void CBC_OneDimWriter::RenderDeviceResult(CFX_RenderDevice* device, + const CFX_Matrix* matrix, + const CFX_WideStringC& contents, + int32_t& e) { + if (m_output == NULL) { + BC_EXCEPTION_CHECK_ReturnVoid(e); + } + CFX_GraphStateData stateData; + CFX_PathData path; + path.AppendRect(0, 0, (FX_FLOAT)m_Width, (FX_FLOAT)m_Height); + device->DrawPath(&path, matrix, &stateData, m_backgroundColor, + m_backgroundColor, FXFILL_ALTERNATE); + CFX_Matrix matri(m_outputHScale, 0.0, 0.0, (FX_FLOAT)m_Height, 0.0, 0.0); + matri.Concat(*matrix); + for (int32_t x = 0; x < m_output->GetWidth(); x++) { + for (int32_t y = 0; y < m_output->GetHeight(); y++) { + CFX_PathData rect; + rect.AppendRect((FX_FLOAT)x, (FX_FLOAT)y, (FX_FLOAT)(x + 1), + (FX_FLOAT)(y + 1)); + CFX_GraphStateData stateData; + if (m_output->Get(x, y)) { + device->DrawPath(&rect, &matri, &stateData, m_barColor, 0, + FXFILL_WINDING); + } + } + } + int32_t i = 0; + for (; i < contents.GetLength(); i++) + if (contents.GetAt(i) != ' ') { + break; + } + if (m_locTextLoc != BC_TEXT_LOC_NONE && i < contents.GetLength()) { + ShowChars(contents, NULL, device, matrix, m_barWidth, m_multiple, e); + BC_EXCEPTION_CHECK_ReturnVoid(e); + } +} +void CBC_OneDimWriter::RenderResult(const CFX_WideStringC& contents, + uint8_t* code, + int32_t codeLength, + FX_BOOL isDevice, + int32_t& e) { + if (codeLength < 1) { + BC_EXCEPTION_CHECK_ReturnVoid(e); + } + if (m_ModuleHeight < 20.0) { + m_ModuleHeight = 20; + } + int32_t codeOldLength = codeLength; + int32_t leftPadding = 0; + int32_t rightPadding = 0; + if (m_bLeftPadding) { + leftPadding = 7; + } + if (m_bRightPadding) { + rightPadding = 7; + } + codeLength += leftPadding; + codeLength += rightPadding; + m_outputHScale = 1.0; + if (m_Width > 0) { + m_outputHScale = (FX_FLOAT)m_Width / (FX_FLOAT)codeLength; + } + if (!isDevice) { + m_outputHScale = + std::max(m_outputHScale, static_cast<FX_FLOAT>(m_ModuleWidth)); + } + FX_FLOAT dataLengthScale = 1.0; + if (m_iDataLenth > 0 && contents.GetLength() != 0) { + dataLengthScale = FX_FLOAT(contents.GetLength()) / FX_FLOAT(m_iDataLenth); + } + if (m_iDataLenth > 0 && contents.GetLength() == 0) { + dataLengthScale = FX_FLOAT(1) / FX_FLOAT(m_iDataLenth); + } + m_multiple = 1; + if (!isDevice) { + m_multiple = (int32_t)ceil(m_outputHScale * dataLengthScale); + } + int32_t outputHeight = 1; + if (!isDevice) { + if (m_Height == 0) { + outputHeight = std::max(20, m_ModuleHeight); + } else { + outputHeight = m_Height; + } + } + int32_t outputWidth = codeLength; + if (!isDevice) { + outputWidth = (int32_t)(codeLength * m_multiple / dataLengthScale); + } + m_barWidth = m_Width; + if (!isDevice) { + m_barWidth = codeLength * m_multiple; + } + m_output = new CBC_CommonBitMatrix; + m_output->Init(outputWidth, outputHeight); + int32_t outputX = leftPadding * m_multiple; + for (int32_t inputX = 0; inputX < codeOldLength; inputX++) { + if (code[inputX] == 1) { + if (outputX >= outputWidth) { + break; + } + if (outputX + m_multiple > outputWidth && outputWidth - outputX > 0) { + m_output->SetRegion(outputX, 0, outputWidth - outputX, outputHeight, e); + break; + } + m_output->SetRegion(outputX, 0, m_multiple, outputHeight, e); + BC_EXCEPTION_CHECK_ReturnVoid(e); + } + outputX += m_multiple; + } +} diff --git a/xfa/fxbarcode/oned/BC_OneDimWriter.h b/xfa/fxbarcode/oned/BC_OneDimWriter.h new file mode 100644 index 0000000000..e91a9297e1 --- /dev/null +++ b/xfa/fxbarcode/oned/BC_OneDimWriter.h @@ -0,0 +1,120 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef XFA_FXBARCODE_ONED_BC_ONEDIMWRITER_H_ +#define XFA_FXBARCODE_ONED_BC_ONEDIMWRITER_H_ + +#include "core/include/fxge/fx_ge.h" +#include "xfa/fxbarcode/BC_Writer.h" +#include "xfa/include/fxbarcode/BC_BarCode.h" + +class CBC_CommonBitMatrix; +class CFX_Font; +class CFX_RenderDevice; + +class CBC_OneDimWriter : public CBC_Writer { + public: + CBC_OneDimWriter(); + virtual ~CBC_OneDimWriter(); + uint8_t* Encode(const CFX_ByteString& contents, + BCFORMAT format, + int32_t& outWidth, + int32_t& outHeight, + int32_t& e); + uint8_t* Encode(const CFX_ByteString& contents, + BCFORMAT format, + int32_t& outWidth, + int32_t& outHeight, + int32_t hints, + int32_t& e); + virtual uint8_t* Encode(const CFX_ByteString& contents, + int32_t& outLength, + int32_t& e) { + return NULL; + } + virtual void RenderResult(const CFX_WideStringC& contents, + uint8_t* code, + int32_t codeLength, + FX_BOOL isDevice, + int32_t& e); + virtual void RenderBitmapResult(CFX_DIBitmap*& pOutBitmap, + const CFX_WideStringC& contents, + int32_t& e); + virtual void RenderDeviceResult(CFX_RenderDevice* device, + const CFX_Matrix* matrix, + const CFX_WideStringC& contents, + int32_t& e); + virtual FX_BOOL CheckContentValidity(const CFX_WideStringC& contents) { + return TRUE; + } + virtual CFX_WideString FilterContents(const CFX_WideStringC& contents) { + return CFX_WideString(); + } + virtual CFX_WideString RenderTextContents(const CFX_WideStringC& contents) { + return CFX_WideString(); + } + virtual void SetPrintChecksum(FX_BOOL checksum); + virtual void SetDataLength(int32_t length); + virtual void SetCalcChecksum(int32_t state); + virtual void SetFontSize(FX_FLOAT size); + virtual void SetFontStyle(int32_t style); + virtual void SetFontColor(FX_ARGB color); + virtual FX_BOOL SetFont(CFX_Font* cFont); + + protected: + FX_BOOL m_bPrintChecksum; + int32_t m_iDataLenth; + FX_BOOL m_bCalcChecksum; + CFX_Font* m_pFont; + FX_FLOAT m_fFontSize; + int32_t m_iFontStyle; + FX_DWORD m_fontColor; + BC_TEXT_LOC m_locTextLoc; + int32_t m_iContentLen; + FX_BOOL m_bLeftPadding; + FX_BOOL m_bRightPadding; + CBC_CommonBitMatrix* m_output; + int32_t m_barWidth; + int32_t m_multiple; + FX_FLOAT m_outputHScale; + void CalcTextInfo(const CFX_ByteString& text, + FXTEXT_CHARPOS* charPos, + CFX_Font* cFont, + FX_FLOAT geWidth, + int32_t fontSize, + FX_FLOAT& charsLen); + virtual void ShowChars(const CFX_WideStringC& contents, + CFX_DIBitmap* pOutBitmap, + CFX_RenderDevice* device, + const CFX_Matrix* matrix, + int32_t barWidth, + int32_t multiple, + int32_t& e); + virtual void ShowBitmapChars(CFX_DIBitmap* pOutBitmap, + const CFX_ByteString str, + FX_FLOAT geWidth, + FXTEXT_CHARPOS* pCharPos, + FX_FLOAT locX, + FX_FLOAT locY, + int32_t barWidth); + virtual void ShowDeviceChars(CFX_RenderDevice* device, + const CFX_Matrix* matrix, + const CFX_ByteString str, + FX_FLOAT geWidth, + FXTEXT_CHARPOS* pCharPos, + FX_FLOAT locX, + FX_FLOAT locY, + int32_t barWidth); + int32_t AppendPattern(uint8_t* target, + int32_t pos, + const int32_t* pattern, + int32_t patternLength, + int32_t startColor, + int32_t& e); + FX_WCHAR Upper(FX_WCHAR ch); +}; + +#endif // XFA_FXBARCODE_ONED_BC_ONEDIMWRITER_H_ diff --git a/xfa/fxbarcode/oned/BC_OnedCodaBarReader.cpp b/xfa/fxbarcode/oned/BC_OnedCodaBarReader.cpp new file mode 100644 index 0000000000..27f2191eac --- /dev/null +++ b/xfa/fxbarcode/oned/BC_OnedCodaBarReader.cpp @@ -0,0 +1,212 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com +// Original code is licensed as follows: +/* + * Copyright 2008 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "xfa/fxbarcode/oned/BC_OnedCodaBarReader.h" + +#include <algorithm> +#include <memory> + +#include "core/include/fxcrt/fx_basic.h" +#include "xfa/fxbarcode/BC_Reader.h" +#include "xfa/fxbarcode/common/BC_CommonBitArray.h" +#include "xfa/fxbarcode/oned/BC_OneDReader.h" +#include "xfa/fxbarcode/oned/BC_OnedCode39Reader.h" +#include "xfa/fxbarcode/utils.h" + +const FX_CHAR* CBC_OnedCodaBarReader::ALPHABET_STRING = + "0123456789-$:/.+ABCDTN"; +const int32_t CBC_OnedCodaBarReader::CHARACTER_ENCODINGS[22] = { + 0x003, 0x006, 0x009, 0x060, 0x012, 0x042, 0x021, 0x024, + 0x030, 0x048, 0x00c, 0x018, 0x045, 0x051, 0x054, 0x015, + 0x01A, 0x029, 0x00B, 0x00E, 0x01A, 0x029}; +const FX_CHAR CBC_OnedCodaBarReader::STARTEND_ENCODING[8] = { + 'E', '*', 'A', 'B', 'C', 'D', 'T', 'N'}; + +CBC_OnedCodaBarReader::CBC_OnedCodaBarReader() {} +CBC_OnedCodaBarReader::~CBC_OnedCodaBarReader() {} +CFX_ByteString CBC_OnedCodaBarReader::DecodeRow(int32_t rowNumber, + CBC_CommonBitArray* row, + int32_t hints, + int32_t& e) { + std::unique_ptr<CFX_Int32Array> start(FindAsteriskPattern(row, e)); + BC_EXCEPTION_CHECK_ReturnValue(e, ""); + (*start)[1] = 0; + int32_t nextStart = (*start)[1]; + int32_t end = row->GetSize(); + while (nextStart < end && !row->Get(nextStart)) { + nextStart++; + } + CFX_ByteString result; + CFX_Int32Array counters; + counters.SetSize(7); + FX_CHAR decodedChar; + int32_t lastStart; + do { + RecordPattern(row, nextStart, &counters, e); + BC_EXCEPTION_CHECK_ReturnValue(e, ""); + decodedChar = ToNarrowWidePattern(&counters); + if (decodedChar == '!') { + e = BCExceptionNotFound; + return ""; + } + result += decodedChar; + lastStart = nextStart; + for (int32_t i = 0; i < counters.GetSize(); i++) { + nextStart += counters[i]; + } + while (nextStart < end && !row->Get(nextStart)) { + nextStart++; + } + } while (nextStart < end); + int32_t lastPatternSize = 0; + for (int32_t j = 0; j < counters.GetSize(); j++) { + lastPatternSize += counters[j]; + } + int32_t whiteSpaceAfterEnd = nextStart - lastStart - lastPatternSize; + if (nextStart != end && (whiteSpaceAfterEnd / 2 < lastPatternSize)) { + e = BCExceptionNotFound; + return ""; + } + if (result.GetLength() < 2) { + e = BCExceptionNotFound; + return ""; + } + FX_CHAR startchar = result[0]; + if (!ArrayContains(STARTEND_ENCODING, startchar)) { + e = BCExceptionNotFound; + return ""; + } + int32_t len = result.GetLength(); + CFX_ByteString temp = result; + for (int32_t k = 1; k < result.GetLength(); k++) { + if (ArrayContains(STARTEND_ENCODING, result[k])) { + if ((k + 1) != result.GetLength()) { + result.Delete(1, k); + k = 1; + } + } + } + if (result.GetLength() < 5) { + int32_t index = temp.Find(result.Mid(1, result.GetLength() - 1)); + if (index == len - (result.GetLength() - 1)) { + e = BCExceptionNotFound; + return ""; + } + } + if (result.GetLength() > minCharacterLength) { + result = result.Mid(1, result.GetLength() - 2); + } else { + e = BCExceptionNotFound; + return ""; + } + return result; +} +CFX_Int32Array* CBC_OnedCodaBarReader::FindAsteriskPattern( + CBC_CommonBitArray* row, + int32_t& e) { + int32_t width = row->GetSize(); + int32_t rowOffset = 0; + while (rowOffset < width) { + if (row->Get(rowOffset)) { + break; + } + rowOffset++; + } + int32_t counterPosition = 0; + CFX_Int32Array counters; + counters.SetSize(7); + int32_t patternStart = rowOffset; + FX_BOOL isWhite = FALSE; + int32_t patternLength = counters.GetSize(); + for (int32_t i = rowOffset; i < width; i++) { + FX_BOOL pixel = row->Get(i); + if (pixel ^ isWhite) { + counters[counterPosition]++; + } else { + if (counterPosition == patternLength - 1) { + if (ArrayContains(STARTEND_ENCODING, ToNarrowWidePattern(&counters))) { + FX_BOOL btemp3 = + row->IsRange(std::max(0, patternStart - (i - patternStart) / 2), + patternStart, FALSE, e); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + if (btemp3) { + CFX_Int32Array* result = new CFX_Int32Array(); + result->SetSize(2); + (*result)[0] = patternStart; + (*result)[1] = i; + return result; + } + } + patternStart += counters[0] + counters[1]; + for (int32_t y = 2; y < patternLength; y++) { + counters[y - 2] = counters[y]; + } + counters[patternLength - 2] = 0; + counters[patternLength - 1] = 0; + counterPosition--; + } else { + counterPosition++; + } + counters[counterPosition] = 1; + isWhite = !isWhite; + } + } + e = BCExceptionNotFound; + return NULL; +} +FX_BOOL CBC_OnedCodaBarReader::ArrayContains(const FX_CHAR array[], + FX_CHAR key) { + for (int32_t i = 0; i < 8; i++) { + if (array[i] == key) { + return TRUE; + } + } + return FALSE; +} +FX_CHAR CBC_OnedCodaBarReader::ToNarrowWidePattern(CFX_Int32Array* counter) { + int32_t numCounters = counter->GetSize(); + if (numCounters < 1) { + return '!'; + } + int32_t averageCounter = 0; + int32_t totalCounters = 0; + for (int32_t i = 0; i < numCounters; i++) { + totalCounters += (*counter)[i]; + } + averageCounter = totalCounters / numCounters; + int32_t pattern = 0; + int32_t wideCounters = 0; + for (int32_t j = 0; j < numCounters; j++) { + if ((*counter)[j] > averageCounter) { + pattern |= 1 << (numCounters - 1 - j); + wideCounters++; + } + } + if ((wideCounters == 2) || (wideCounters == 3)) { + for (int32_t k = 0; k < 22; k++) { + if (CHARACTER_ENCODINGS[k] == pattern) { + return (ALPHABET_STRING)[k]; + } + } + } + return '!'; +} diff --git a/xfa/fxbarcode/oned/BC_OnedCodaBarReader.h b/xfa/fxbarcode/oned/BC_OnedCodaBarReader.h new file mode 100644 index 0000000000..678795dcf3 --- /dev/null +++ b/xfa/fxbarcode/oned/BC_OnedCodaBarReader.h @@ -0,0 +1,36 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef XFA_FXBARCODE_ONED_BC_ONEDCODABARREADER_H_ +#define XFA_FXBARCODE_ONED_BC_ONEDCODABARREADER_H_ + +#include "core/include/fxcrt/fx_basic.h" +#include "xfa/fxbarcode/oned/BC_OneDReader.h" + +class CBC_CommonBitArray; +class CBC_OneDReader; + +class CBC_OnedCodaBarReader : public CBC_OneDReader { + public: + CBC_OnedCodaBarReader(); + virtual ~CBC_OnedCodaBarReader(); + CFX_ByteString DecodeRow(int32_t rowNumber, + CBC_CommonBitArray* row, + int32_t hints, + int32_t& e); + CFX_Int32Array* FindAsteriskPattern(CBC_CommonBitArray* row, int32_t& e); + FX_BOOL ArrayContains(const FX_CHAR array[], FX_CHAR key); + FX_CHAR ToNarrowWidePattern(CFX_Int32Array* counter); + + static const FX_CHAR* ALPHABET_STRING; + static const int32_t CHARACTER_ENCODINGS[22]; + + private: + static const int32_t minCharacterLength = 3; + static const FX_CHAR STARTEND_ENCODING[8]; +}; + +#endif // XFA_FXBARCODE_ONED_BC_ONEDCODABARREADER_H_ diff --git a/xfa/fxbarcode/oned/BC_OnedCodaBarWriter.cpp b/xfa/fxbarcode/oned/BC_OnedCodaBarWriter.cpp new file mode 100644 index 0000000000..81f0339aa8 --- /dev/null +++ b/xfa/fxbarcode/oned/BC_OnedCodaBarWriter.cpp @@ -0,0 +1,231 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com +// Original code is licensed as follows: +/* + * Copyright 2011 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "xfa/fxbarcode/BC_Reader.h" +#include "xfa/fxbarcode/BC_Writer.h" +#include "xfa/fxbarcode/common/BC_CommonBitArray.h" +#include "xfa/fxbarcode/common/BC_CommonBitMatrix.h" +#include "xfa/fxbarcode/oned/BC_OneDReader.h" +#include "xfa/fxbarcode/oned/BC_OneDimWriter.h" +#include "xfa/fxbarcode/oned/BC_OnedCodaBarReader.h" +#include "xfa/fxbarcode/oned/BC_OnedCodaBarWriter.h" + +const FX_CHAR CBC_OnedCodaBarWriter::START_END_CHARS[] = { + 'A', 'B', 'C', 'D', 'T', 'N', '*', 'E', 'a', 'b', 'c', 'd', 't', 'n', 'e'}; +const FX_CHAR CBC_OnedCodaBarWriter::CONTENT_CHARS[] = { + '0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', '-', '$', '/', ':', '+', '.'}; + +CBC_OnedCodaBarWriter::CBC_OnedCodaBarWriter() { + m_chStart = 'A'; + m_chEnd = 'B'; + m_iWideNarrRatio = 2; +} +CBC_OnedCodaBarWriter::~CBC_OnedCodaBarWriter() {} +FX_BOOL CBC_OnedCodaBarWriter::SetStartChar(FX_CHAR start) { + for (size_t i = 0; i < FX_ArraySize(START_END_CHARS); ++i) { + if (START_END_CHARS[i] == start) { + m_chStart = start; + return TRUE; + } + } + return FALSE; +} + +FX_BOOL CBC_OnedCodaBarWriter::SetEndChar(FX_CHAR end) { + for (size_t i = 0; i < FX_ArraySize(START_END_CHARS); ++i) { + if (START_END_CHARS[i] == end) { + m_chEnd = end; + return TRUE; + } + } + return FALSE; +} +void CBC_OnedCodaBarWriter::SetDataLength(int32_t length) { + m_iDataLenth = length + 2; +} +FX_BOOL CBC_OnedCodaBarWriter::SetTextLocation(BC_TEXT_LOC location) { + if (location < BC_TEXT_LOC_NONE || location > BC_TEXT_LOC_BELOWEMBED) { + return FALSE; + } + m_locTextLoc = location; + return TRUE; +} +FX_BOOL CBC_OnedCodaBarWriter::SetWideNarrowRatio(int32_t ratio) { + if (ratio < 2 || ratio > 3) { + return FALSE; + } + m_iWideNarrRatio = ratio; + return TRUE; +} +FX_BOOL CBC_OnedCodaBarWriter::FindChar(FX_WCHAR ch, FX_BOOL isContent) { + if (isContent) { + for (size_t i = 0; i < FX_ArraySize(CONTENT_CHARS); ++i) { + if (ch == (FX_WCHAR)CONTENT_CHARS[i]) { + return TRUE; + } + } + for (size_t j = 0; j < FX_ArraySize(START_END_CHARS); ++j) { + if (ch == (FX_WCHAR)START_END_CHARS[j]) { + return TRUE; + } + } + return FALSE; + } else { + for (size_t i = 0; i < FX_ArraySize(CONTENT_CHARS); ++i) { + if (ch == (FX_WCHAR)CONTENT_CHARS[i]) { + return TRUE; + } + } + return FALSE; + } +} +FX_BOOL CBC_OnedCodaBarWriter::CheckContentValidity( + const CFX_WideStringC& contents) { + FX_WCHAR ch; + int32_t index = 0; + for (index = 0; index < contents.GetLength(); index++) { + ch = contents.GetAt(index); + if (FindChar(ch, FALSE)) { + continue; + } else { + return FALSE; + } + } + return TRUE; +} +CFX_WideString CBC_OnedCodaBarWriter::FilterContents( + const CFX_WideStringC& contents) { + CFX_WideString filtercontents; + FX_WCHAR ch; + for (int32_t index = 0; index < contents.GetLength(); index++) { + ch = contents.GetAt(index); + if (ch > 175) { + index++; + continue; + } + if (FindChar(ch, TRUE)) { + filtercontents += ch; + } else { + continue; + } + } + return filtercontents; +} +uint8_t* CBC_OnedCodaBarWriter::Encode(const CFX_ByteString& contents, + BCFORMAT format, + int32_t& outWidth, + int32_t& outHeight, + int32_t& e) { + uint8_t* ret = Encode(contents, format, outWidth, outHeight, 0, e); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + return ret; +} +uint8_t* CBC_OnedCodaBarWriter::Encode(const CFX_ByteString& contents, + BCFORMAT format, + int32_t& outWidth, + int32_t& outHeight, + int32_t hints, + int32_t& e) { + if (format != BCFORMAT_CODABAR) { + e = BCExceptionOnlyEncodeCODEBAR; + return NULL; + } + uint8_t* ret = + CBC_OneDimWriter::Encode(contents, format, outWidth, outHeight, hints, e); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + return ret; +} +uint8_t* CBC_OnedCodaBarWriter::Encode(const CFX_ByteString& contents, + int32_t& outLength, + int32_t& e) { + CBC_OnedCodaBarReader CodaBarR; + CFX_ByteString data = m_chStart + contents + m_chEnd; + m_iContentLen = data.GetLength(); + uint8_t* result = FX_Alloc2D(uint8_t, m_iWideNarrRatio * 7, data.GetLength()); + FX_CHAR ch; + int32_t position = 0; + for (int32_t index = 0; index < data.GetLength(); index++) { + ch = data.GetAt(index); + if (((ch >= 'a') && (ch <= 'z'))) { + ch = ch - 32; + } + switch (ch) { + case 'T': + ch = 'A'; + break; + case 'N': + ch = 'B'; + break; + case '*': + ch = 'C'; + break; + case 'E': + ch = 'D'; + break; + default: + break; + } + int32_t code = 0; + int32_t len = (int32_t)strlen(CodaBarR.ALPHABET_STRING); + for (int32_t i = 0; i < len; i++) { + if (ch == CodaBarR.ALPHABET_STRING[i]) { + code = CodaBarR.CHARACTER_ENCODINGS[i]; + break; + } + } + uint8_t color = 1; + int32_t counter = 0; + int32_t bit = 0; + while (bit < 7) { + result[position] = color; + position++; + if (((code >> (6 - bit)) & 1) == 0 || counter == m_iWideNarrRatio - 1) { + color = !color; + bit++; + counter = 0; + } else { + counter++; + } + } + if (index < data.GetLength() - 1) { + result[position] = 0; + position++; + } + } + outLength = position; + return result; +} +CFX_WideString CBC_OnedCodaBarWriter::encodedContents( + const CFX_WideStringC& contents) { + CFX_WideString strStart(m_chStart); + CFX_WideString strEnd(m_chEnd); + return strStart + contents + strEnd; +} +void CBC_OnedCodaBarWriter::RenderResult(const CFX_WideStringC& contents, + uint8_t* code, + int32_t codeLength, + FX_BOOL isDevice, + int32_t& e) { + CBC_OneDimWriter::RenderResult(encodedContents(contents), code, codeLength, + isDevice, e); +} diff --git a/xfa/fxbarcode/oned/BC_OnedCodaBarWriter.h b/xfa/fxbarcode/oned/BC_OnedCodaBarWriter.h new file mode 100644 index 0000000000..92a31bd989 --- /dev/null +++ b/xfa/fxbarcode/oned/BC_OnedCodaBarWriter.h @@ -0,0 +1,54 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef XFA_FXBARCODE_ONED_BC_ONEDCODABARWRITER_H_ +#define XFA_FXBARCODE_ONED_BC_ONEDCODABARWRITER_H_ + +enum BC_TEXT_LOC; +class CBC_OneDimWriter; +class CBC_OnedCodaBarWriter; +class CBC_OnedCodaBarWriter : public CBC_OneDimWriter { + public: + CBC_OnedCodaBarWriter(); + virtual ~CBC_OnedCodaBarWriter(); + uint8_t* Encode(const CFX_ByteString& contents, + int32_t& outLength, + int32_t& e); + uint8_t* Encode(const CFX_ByteString& contents, + BCFORMAT format, + int32_t& outWidth, + int32_t& outHeight, + int32_t& e); + uint8_t* Encode(const CFX_ByteString& contents, + BCFORMAT format, + int32_t& outWidth, + int32_t& outHeight, + int32_t hints, + int32_t& e); + CFX_WideString encodedContents(const CFX_WideStringC& contents); + FX_BOOL CheckContentValidity(const CFX_WideStringC& contents); + CFX_WideString FilterContents(const CFX_WideStringC& contents); + FX_BOOL SetStartChar(FX_CHAR start); + FX_BOOL SetEndChar(FX_CHAR end); + void SetDataLength(int32_t length); + FX_BOOL SetTextLocation(BC_TEXT_LOC location); + FX_BOOL SetWideNarrowRatio(int32_t ratio); + FX_BOOL FindChar(FX_WCHAR ch, FX_BOOL isContent); + + private: + void RenderResult(const CFX_WideStringC& contents, + uint8_t* code, + int32_t codeLength, + FX_BOOL isDevice, + int32_t& e); + static const FX_CHAR START_END_CHARS[]; + static const FX_CHAR CONTENT_CHARS[]; + FX_CHAR m_chStart; + FX_CHAR m_chEnd; + int32_t m_iWideNarrRatio; +}; + +#endif // XFA_FXBARCODE_ONED_BC_ONEDCODABARWRITER_H_ diff --git a/xfa/fxbarcode/oned/BC_OnedCode128Reader.cpp b/xfa/fxbarcode/oned/BC_OnedCode128Reader.cpp new file mode 100644 index 0000000000..b5f5aa5fe4 --- /dev/null +++ b/xfa/fxbarcode/oned/BC_OnedCode128Reader.cpp @@ -0,0 +1,351 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com +// Original code is licensed as follows: +/* + * Copyright 2008 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <algorithm> + +#include "xfa/fxbarcode/BC_Reader.h" +#include "xfa/fxbarcode/common/BC_CommonBitArray.h" +#include "xfa/fxbarcode/oned/BC_OneDReader.h" +#include "xfa/fxbarcode/oned/BC_OnedCode128Reader.h" +#include "xfa/fxbarcode/utils.h" + +const int32_t CBC_OnedCode128Reader::CODE_PATTERNS[107][7] = { + {2, 1, 2, 2, 2, 2, 0}, {2, 2, 2, 1, 2, 2, 0}, {2, 2, 2, 2, 2, 1, 0}, + {1, 2, 1, 2, 2, 3, 0}, {1, 2, 1, 3, 2, 2, 0}, {1, 3, 1, 2, 2, 2, 0}, + {1, 2, 2, 2, 1, 3, 0}, {1, 2, 2, 3, 1, 2, 0}, {1, 3, 2, 2, 1, 2, 0}, + {2, 2, 1, 2, 1, 3, 0}, {2, 2, 1, 3, 1, 2, 0}, {2, 3, 1, 2, 1, 2, 0}, + {1, 1, 2, 2, 3, 2, 0}, {1, 2, 2, 1, 3, 2, 0}, {1, 2, 2, 2, 3, 1, 0}, + {1, 1, 3, 2, 2, 2, 0}, {1, 2, 3, 1, 2, 2, 0}, {1, 2, 3, 2, 2, 1, 0}, + {2, 2, 3, 2, 1, 1, 0}, {2, 2, 1, 1, 3, 2, 0}, {2, 2, 1, 2, 3, 1, 0}, + {2, 1, 3, 2, 1, 2, 0}, {2, 2, 3, 1, 1, 2, 0}, {3, 1, 2, 1, 3, 1, 0}, + {3, 1, 1, 2, 2, 2, 0}, {3, 2, 1, 1, 2, 2, 0}, {3, 2, 1, 2, 2, 1, 0}, + {3, 1, 2, 2, 1, 2, 0}, {3, 2, 2, 1, 1, 2, 0}, {3, 2, 2, 2, 1, 1, 0}, + {2, 1, 2, 1, 2, 3, 0}, {2, 1, 2, 3, 2, 1, 0}, {2, 3, 2, 1, 2, 1, 0}, + {1, 1, 1, 3, 2, 3, 0}, {1, 3, 1, 1, 2, 3, 0}, {1, 3, 1, 3, 2, 1, 0}, + {1, 1, 2, 3, 1, 3, 0}, {1, 3, 2, 1, 1, 3, 0}, {1, 3, 2, 3, 1, 1, 0}, + {2, 1, 1, 3, 1, 3, 0}, {2, 3, 1, 1, 1, 3, 0}, {2, 3, 1, 3, 1, 1, 0}, + {1, 1, 2, 1, 3, 3, 0}, {1, 1, 2, 3, 3, 1, 0}, {1, 3, 2, 1, 3, 1, 0}, + {1, 1, 3, 1, 2, 3, 0}, {1, 1, 3, 3, 2, 1, 0}, {1, 3, 3, 1, 2, 1, 0}, + {3, 1, 3, 1, 2, 1, 0}, {2, 1, 1, 3, 3, 1, 0}, {2, 3, 1, 1, 3, 1, 0}, + {2, 1, 3, 1, 1, 3, 0}, {2, 1, 3, 3, 1, 1, 0}, {2, 1, 3, 1, 3, 1, 0}, + {3, 1, 1, 1, 2, 3, 0}, {3, 1, 1, 3, 2, 1, 0}, {3, 3, 1, 1, 2, 1, 0}, + {3, 1, 2, 1, 1, 3, 0}, {3, 1, 2, 3, 1, 1, 0}, {3, 3, 2, 1, 1, 1, 0}, + {3, 1, 4, 1, 1, 1, 0}, {2, 2, 1, 4, 1, 1, 0}, {4, 3, 1, 1, 1, 1, 0}, + {1, 1, 1, 2, 2, 4, 0}, {1, 1, 1, 4, 2, 2, 0}, {1, 2, 1, 1, 2, 4, 0}, + {1, 2, 1, 4, 2, 1, 0}, {1, 4, 1, 1, 2, 2, 0}, {1, 4, 1, 2, 2, 1, 0}, + {1, 1, 2, 2, 1, 4, 0}, {1, 1, 2, 4, 1, 2, 0}, {1, 2, 2, 1, 1, 4, 0}, + {1, 2, 2, 4, 1, 1, 0}, {1, 4, 2, 1, 1, 2, 0}, {1, 4, 2, 2, 1, 1, 0}, + {2, 4, 1, 2, 1, 1, 0}, {2, 2, 1, 1, 1, 4, 0}, {4, 1, 3, 1, 1, 1, 0}, + {2, 4, 1, 1, 1, 2, 0}, {1, 3, 4, 1, 1, 1, 0}, {1, 1, 1, 2, 4, 2, 0}, + {1, 2, 1, 1, 4, 2, 0}, {1, 2, 1, 2, 4, 1, 0}, {1, 1, 4, 2, 1, 2, 0}, + {1, 2, 4, 1, 1, 2, 0}, {1, 2, 4, 2, 1, 1, 0}, {4, 1, 1, 2, 1, 2, 0}, + {4, 2, 1, 1, 1, 2, 0}, {4, 2, 1, 2, 1, 1, 0}, {2, 1, 2, 1, 4, 1, 0}, + {2, 1, 4, 1, 2, 1, 0}, {4, 1, 2, 1, 2, 1, 0}, {1, 1, 1, 1, 4, 3, 0}, + {1, 1, 1, 3, 4, 1, 0}, {1, 3, 1, 1, 4, 1, 0}, {1, 1, 4, 1, 1, 3, 0}, + {1, 1, 4, 3, 1, 1, 0}, {4, 1, 1, 1, 1, 3, 0}, {4, 1, 1, 3, 1, 1, 0}, + {1, 1, 3, 1, 4, 1, 0}, {1, 1, 4, 1, 3, 1, 0}, {3, 1, 1, 1, 4, 1, 0}, + {4, 1, 1, 1, 3, 1, 0}, {2, 1, 1, 4, 1, 2, 0}, {2, 1, 1, 2, 1, 4, 0}, + {2, 1, 1, 2, 3, 2, 0}, {2, 3, 3, 1, 1, 1, 2}}; + +CBC_OnedCode128Reader::CBC_OnedCode128Reader() {} +CBC_OnedCode128Reader::~CBC_OnedCode128Reader() {} +CFX_Int32Array* CBC_OnedCode128Reader::FindStartPattern(CBC_CommonBitArray* row, + int32_t& e) { + int32_t width = row->GetSize(); + int32_t rowOffset = 0; + while (rowOffset < width) { + if (row->Get(rowOffset)) { + break; + } + rowOffset++; + } + int32_t counterPosition = 0; + CFX_Int32Array counters; + counters.SetSize(6); + int32_t patternStart = rowOffset; + FX_BOOL isWhite = FALSE; + int32_t patternLength = counters.GetSize(); + for (int32_t i = rowOffset; i < width; i++) { + FX_BOOL pixel = row->Get(i); + if (pixel ^ isWhite) { + counters[counterPosition]++; + } else { + if (counterPosition == patternLength - 1) { + int32_t bestVariance = MAX_AVG_VARIANCE; + int32_t bestMatch = -1; + for (int32_t startCode = CODE_START_A; startCode <= CODE_START_C; + startCode++) { + int32_t variance = PatternMatchVariance( + &counters, &CODE_PATTERNS[startCode][0], MAX_INDIVIDUAL_VARIANCE); + if (variance < bestVariance) { + bestVariance = variance; + bestMatch = startCode; + } + } + if (bestMatch >= 0) { + FX_BOOL btemp2 = + row->IsRange(std::max(0, patternStart - (i - patternStart) / 2), + patternStart, FALSE, e); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + if (btemp2) { + CFX_Int32Array* result = new CFX_Int32Array; + result->SetSize(3); + (*result)[0] = patternStart; + (*result)[1] = i; + (*result)[2] = bestMatch; + return result; + } + } + patternStart += counters[0] + counters[1]; + for (int32_t y = 2; y < patternLength; y++) { + counters[y - 2] = counters[y]; + } + counters[patternLength - 2] = 0; + counters[patternLength - 1] = 0; + counterPosition--; + } else { + counterPosition++; + } + counters[counterPosition] = 1; + isWhite = !isWhite; + } + } + e = BCExceptionNotFound; + return NULL; +} +int32_t CBC_OnedCode128Reader::DecodeCode(CBC_CommonBitArray* row, + CFX_Int32Array* counters, + int32_t rowOffset, + int32_t& e) { + RecordPattern(row, rowOffset, counters, e); + BC_EXCEPTION_CHECK_ReturnValue(e, 0); + int32_t bestVariance = MAX_AVG_VARIANCE; + int32_t bestMatch = -1; + for (int32_t d = 0; d < 107; d++) { + int32_t variance = PatternMatchVariance(counters, &CODE_PATTERNS[d][0], + MAX_INDIVIDUAL_VARIANCE); + if (variance < bestVariance) { + bestVariance = variance; + bestMatch = d; + } + } + if (bestMatch >= 0) { + return bestMatch; + } else { + e = BCExceptionNotFound; + return 0; + } + return 0; +} +CFX_ByteString CBC_OnedCode128Reader::DecodeRow(int32_t rowNumber, + CBC_CommonBitArray* row, + int32_t hints, + int32_t& e) { + CFX_Int32Array* startPatternInfo = FindStartPattern(row, e); + BC_EXCEPTION_CHECK_ReturnValue(e, ""); + int32_t startCode = (*startPatternInfo)[2]; + int32_t codeSet; + switch (startCode) { + case 103: + codeSet = CODE_CODE_A; + break; + case 104: + codeSet = CODE_CODE_B; + break; + case 105: + codeSet = CODE_CODE_C; + break; + default: + if (startPatternInfo) { + startPatternInfo->RemoveAll(); + delete startPatternInfo; + startPatternInfo = NULL; + } + e = BCExceptionFormatException; + return ""; + } + FX_BOOL done = FALSE; + FX_BOOL isNextShifted = FALSE; + CFX_ByteString result; + int32_t lastStart = (*startPatternInfo)[0]; + int32_t nextStart = (*startPatternInfo)[1]; + if (startPatternInfo) { + startPatternInfo->RemoveAll(); + delete startPatternInfo; + startPatternInfo = NULL; + } + CFX_Int32Array counters; + counters.SetSize(6); + int32_t lastCode = 0; + int32_t code = 0; + int32_t checksumTotal = startCode; + int32_t multiplier = 0; + FX_BOOL lastCharacterWasPrintable = TRUE; + while (!done) { + FX_BOOL unshift = isNextShifted; + isNextShifted = FALSE; + lastCode = code; + code = DecodeCode(row, &counters, nextStart, e); + BC_EXCEPTION_CHECK_ReturnValue(e, ""); + if (code != CODE_STOP) { + lastCharacterWasPrintable = TRUE; + } + if (code != CODE_STOP) { + multiplier++; + checksumTotal += multiplier * code; + } + lastStart = nextStart; + for (int32_t i = 0; i < counters.GetSize(); i++) { + nextStart += counters[i]; + } + switch (code) { + case 103: + case 104: + case 105: + e = BCExceptionFormatException; + return ""; + } + switch (codeSet) { + case 101: + if (code < 64) { + result += (FX_CHAR)(' ' + code); + } else if (code < 96) { + result += (FX_CHAR)(code - 64); + } else { + if (code != CODE_STOP) { + lastCharacterWasPrintable = FALSE; + } + switch (code) { + case 102: + case 97: + case 96: + case 101: + break; + case 98: + isNextShifted = TRUE; + codeSet = CODE_CODE_B; + break; + case 100: + codeSet = CODE_CODE_B; + break; + case 99: + codeSet = CODE_CODE_C; + break; + case 106: + done = TRUE; + break; + } + } + break; + case 100: + if (code < 96) { + result += (FX_CHAR)(' ' + code); + } else { + if (code != CODE_STOP) { + lastCharacterWasPrintable = FALSE; + } + switch (code) { + case 102: + case 97: + case 96: + case 100: + break; + case 98: + isNextShifted = TRUE; + codeSet = CODE_CODE_A; + break; + case 101: + codeSet = CODE_CODE_A; + break; + case 99: + codeSet = CODE_CODE_C; + break; + case 106: + done = TRUE; + break; + } + } + break; + case 99: + if (code < 100) { + if (code < 10) { + result += '0'; + } + FX_CHAR temp[128]; + // TODO(dsinclair): Should this be snprintf? + sprintf(temp, "%d", code); + result += temp; + } else { + if (code != CODE_STOP) { + lastCharacterWasPrintable = FALSE; + } + switch (code) { + case 102: + break; + case 101: + codeSet = CODE_CODE_A; + break; + case 100: + codeSet = CODE_CODE_B; + break; + case 106: + done = TRUE; + break; + } + } + break; + } + if (unshift) { + codeSet = codeSet == CODE_CODE_A ? CODE_CODE_B : CODE_CODE_A; + } + } + int32_t width = row->GetSize(); + while (nextStart < width && row->Get(nextStart)) { + nextStart++; + } + FX_BOOL boolT1 = row->IsRange( + nextStart, std::min(width, nextStart + (nextStart - lastStart) / 2), + FALSE, e); + BC_EXCEPTION_CHECK_ReturnValue(e, ""); + if (!boolT1) { + e = BCExceptionNotFound; + return ""; + } + checksumTotal -= multiplier * lastCode; + if (checksumTotal % 103 != lastCode) { + e = BCExceptionChecksumException; + return ""; + } + int32_t resultLength = result.GetLength(); + if (resultLength > 0 && lastCharacterWasPrintable) { + if (codeSet == CODE_CODE_C) { + result = result.Mid(0, result.GetLength() - 2); + } else { + result = result.Mid(0, result.GetLength() - 1); + } + } + if (result.GetLength() == 0) { + e = BCExceptionFormatException; + return ""; + } + return result; +} diff --git a/xfa/fxbarcode/oned/BC_OnedCode128Reader.h b/xfa/fxbarcode/oned/BC_OnedCode128Reader.h new file mode 100644 index 0000000000..d9ac4853bf --- /dev/null +++ b/xfa/fxbarcode/oned/BC_OnedCode128Reader.h @@ -0,0 +1,49 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef XFA_FXBARCODE_ONED_BC_ONEDCODE128READER_H_ +#define XFA_FXBARCODE_ONED_BC_ONEDCODE128READER_H_ + +class CBC_OneDReader; +class CBC_CommonBitArray; +class CBC_OnedCode128Reader : public CBC_OneDReader { + public: + CBC_OnedCode128Reader(); + virtual ~CBC_OnedCode128Reader(); + virtual CFX_ByteString DecodeRow(int32_t rowNumber, + CBC_CommonBitArray* row, + int32_t hints, + int32_t& e); + + static const int32_t CODE_PATTERNS[107][7]; + + private: + static const int32_t MAX_AVG_VARIANCE = (int32_t)(256 * 0.25f); + static const int32_t MAX_INDIVIDUAL_VARIANCE = (int32_t)(256 * 0.7f); + + static const int32_t CODE_SHIFT = 98; + static const int32_t CODE_CODE_C = 99; + static const int32_t CODE_CODE_B = 100; + static const int32_t CODE_CODE_A = 101; + static const int32_t CODE_FNC_1 = 102; + static const int32_t CODE_FNC_2 = 97; + static const int32_t CODE_FNC_3 = 96; + static const int32_t CODE_FNC_4_A = 101; + static const int32_t CODE_FNC_4_B = 100; + + static const int32_t CODE_START_A = 103; + static const int32_t CODE_START_B = 104; + static const int32_t CODE_START_C = 105; + static const int32_t CODE_STOP = 106; + + CFX_Int32Array* FindStartPattern(CBC_CommonBitArray* row, int32_t& e); + int32_t DecodeCode(CBC_CommonBitArray* row, + CFX_Int32Array* counters, + int32_t rowOffset, + int32_t& e); +}; + +#endif // XFA_FXBARCODE_ONED_BC_ONEDCODE128READER_H_ diff --git a/xfa/fxbarcode/oned/BC_OnedCode128Writer.cpp b/xfa/fxbarcode/oned/BC_OnedCode128Writer.cpp new file mode 100644 index 0000000000..4d759b48a3 --- /dev/null +++ b/xfa/fxbarcode/oned/BC_OnedCode128Writer.cpp @@ -0,0 +1,235 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com +// Original code is licensed as follows: +/* + * Copyright 2010 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "xfa/fxbarcode/BC_Reader.h" +#include "xfa/fxbarcode/BC_Writer.h" +#include "xfa/fxbarcode/oned/BC_OneDReader.h" +#include "xfa/fxbarcode/oned/BC_OneDimWriter.h" +#include "xfa/fxbarcode/oned/BC_OnedCode128Reader.h" +#include "xfa/fxbarcode/oned/BC_OnedCode128Writer.h" + +const int32_t CBC_OnedCode128Writer::CODE_CODE_B = 100; +const int32_t CBC_OnedCode128Writer::CODE_CODE_C = 99; +const int32_t CBC_OnedCode128Writer::CODE_START_B = 104; +const int32_t CBC_OnedCode128Writer::CODE_START_C = 105; +const int32_t CBC_OnedCode128Writer::CODE_STOP = 106; + +CBC_OnedCode128Writer::CBC_OnedCode128Writer() { + m_codeFormat = BC_CODE128_B; +} +CBC_OnedCode128Writer::CBC_OnedCode128Writer(BC_TYPE type) { + m_codeFormat = type; +} +CBC_OnedCode128Writer::~CBC_OnedCode128Writer() {} +BC_TYPE CBC_OnedCode128Writer::GetType() { + return m_codeFormat; +} +FX_BOOL CBC_OnedCode128Writer::CheckContentValidity( + const CFX_WideStringC& contents) { + FX_BOOL ret = TRUE; + int32_t position = 0; + int32_t patternIndex = -1; + if (m_codeFormat == BC_CODE128_B || m_codeFormat == BC_CODE128_C) { + while (position < contents.GetLength()) { + patternIndex = (int32_t)contents.GetAt(position); + if (patternIndex >= 32 && patternIndex <= 126 && patternIndex != 34) { + position++; + continue; + } else { + ret = FALSE; + break; + } + position++; + } + } else { + ret = FALSE; + } + return ret; +} +CFX_WideString CBC_OnedCode128Writer::FilterContents( + const CFX_WideStringC& contents) { + CFX_WideString filterChineseChar; + FX_WCHAR ch; + for (int32_t i = 0; i < contents.GetLength(); i++) { + ch = contents.GetAt(i); + if (ch > 175) { + i++; + continue; + } + filterChineseChar += ch; + } + CFX_WideString filtercontents; + if (m_codeFormat == BC_CODE128_B) { + for (int32_t i = 0; i < filterChineseChar.GetLength(); i++) { + ch = filterChineseChar.GetAt(i); + if (ch >= 32 && ch <= 126) { + filtercontents += ch; + } else { + continue; + } + } + } else if (m_codeFormat == BC_CODE128_C) { + for (int32_t i = 0; i < filterChineseChar.GetLength(); i++) { + ch = filterChineseChar.GetAt(i); + if (ch >= 32 && ch <= 106) { + filtercontents += ch; + } else { + continue; + } + } + } else { + filtercontents = contents; + } + return filtercontents; +} +FX_BOOL CBC_OnedCode128Writer::SetTextLocation(BC_TEXT_LOC location) { + if (location < BC_TEXT_LOC_NONE || location > BC_TEXT_LOC_BELOWEMBED) { + return FALSE; + } + m_locTextLoc = location; + return TRUE; +} +uint8_t* CBC_OnedCode128Writer::Encode(const CFX_ByteString& contents, + BCFORMAT format, + int32_t& outWidth, + int32_t& outHeight, + int32_t hints, + int32_t& e) { + if (format != BCFORMAT_CODE_128) { + e = BCExceptionOnlyEncodeCODE_128; + return NULL; + } + uint8_t* ret = + CBC_OneDimWriter::Encode(contents, format, outWidth, outHeight, hints, e); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + return ret; +} +uint8_t* CBC_OnedCode128Writer::Encode(const CFX_ByteString& contents, + BCFORMAT format, + int32_t& outWidth, + int32_t& outHeight, + int32_t& e) { + uint8_t* ret = Encode(contents, format, outWidth, outHeight, 0, e); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + return ret; +} +FX_BOOL CBC_OnedCode128Writer::IsDigits(const CFX_ByteString& contents, + int32_t start, + int32_t length) { + int32_t end = start + length; + for (int32_t i = start; i < end; i++) { + if (contents[i] < '0' || contents[i] > '9') { + return FALSE; + } + } + return TRUE; +} +uint8_t* CBC_OnedCode128Writer::Encode(const CFX_ByteString& contents, + int32_t& outLength, + int32_t& e) { + if (contents.GetLength() < 1 || contents.GetLength() > 80) { + e = BCExceptionContentsLengthShouldBetween1and80; + return NULL; + } + CFX_PtrArray patterns; + int32_t checkSum = 0; + if (m_codeFormat == BC_CODE128_B) { + checkSum = Encode128B(contents, patterns); + } else if (m_codeFormat == BC_CODE128_C) { + checkSum = Encode128C(contents, patterns); + } else { + e = BCExceptionFormatException; + return NULL; + } + checkSum %= 103; + patterns.Add((int32_t*)CBC_OnedCode128Reader::CODE_PATTERNS[checkSum]); + patterns.Add((int32_t*)CBC_OnedCode128Reader::CODE_PATTERNS[CODE_STOP]); + m_iContentLen = contents.GetLength() + 3; + int32_t codeWidth = 0; + for (int32_t k = 0; k < patterns.GetSize(); k++) { + int32_t* pattern = (int32_t*)patterns[k]; + for (int32_t j = 0; j < 7; j++) { + codeWidth += pattern[j]; + } + } + outLength = codeWidth; + uint8_t* result = FX_Alloc(uint8_t, outLength); + int32_t pos = 0; + for (int32_t j = 0; j < patterns.GetSize(); j++) { + int32_t* pattern = (int32_t*)patterns[j]; + pos += AppendPattern(result, pos, pattern, 7, 1, e); + if (e != BCExceptionNO) { + FX_Free(result); + return NULL; + } + } + return result; +} +int32_t CBC_OnedCode128Writer::Encode128B(const CFX_ByteString& contents, + CFX_PtrArray& patterns) { + int32_t checkSum = 0; + int32_t checkWeight = 1; + int32_t position = 0; + patterns.Add((int32_t*)CBC_OnedCode128Reader::CODE_PATTERNS[CODE_START_B]); + checkSum += CODE_START_B * checkWeight; + while (position < contents.GetLength()) { + int32_t patternIndex = 0; + patternIndex = contents[position] - ' '; + position += 1; + patterns.Add((int32_t*)CBC_OnedCode128Reader::CODE_PATTERNS[patternIndex]); + checkSum += patternIndex * checkWeight; + if (position != 0) { + checkWeight++; + } + } + return checkSum; +} +int32_t CBC_OnedCode128Writer::Encode128C(const CFX_ByteString& contents, + CFX_PtrArray& patterns) { + int32_t checkSum = 0; + int32_t checkWeight = 1; + int32_t position = 0; + patterns.Add((int32_t*)CBC_OnedCode128Reader::CODE_PATTERNS[CODE_START_C]); + checkSum += CODE_START_C * checkWeight; + while (position < contents.GetLength()) { + int32_t patternIndex = 0; + FX_CHAR ch = contents.GetAt(position); + if (ch < '0' || ch > '9') { + patternIndex = (int32_t)ch; + position++; + } else { + patternIndex = FXSYS_atoi(contents.Mid(position, 2)); + if (contents.GetAt(position + 1) < '0' || + contents.GetAt(position + 1) > '9') { + position += 1; + } else { + position += 2; + } + } + patterns.Add((int32_t*)CBC_OnedCode128Reader::CODE_PATTERNS[patternIndex]); + checkSum += patternIndex * checkWeight; + if (position != 0) { + checkWeight++; + } + } + return checkSum; +} diff --git a/xfa/fxbarcode/oned/BC_OnedCode128Writer.h b/xfa/fxbarcode/oned/BC_OnedCode128Writer.h new file mode 100644 index 0000000000..9be05a19b0 --- /dev/null +++ b/xfa/fxbarcode/oned/BC_OnedCode128Writer.h @@ -0,0 +1,49 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef XFA_FXBARCODE_ONED_BC_ONEDCODE128WRITER_H_ +#define XFA_FXBARCODE_ONED_BC_ONEDCODE128WRITER_H_ + +class CBC_OneDimWriter; +class CBC_OnedCode128Writer : public CBC_OneDimWriter { + public: + CBC_OnedCode128Writer(); + CBC_OnedCode128Writer(BC_TYPE type); + virtual ~CBC_OnedCode128Writer(); + uint8_t* Encode(const CFX_ByteString& contents, + BCFORMAT format, + int32_t& outWidth, + int32_t& outHeight, + int32_t hints, + int32_t& e); + uint8_t* Encode(const CFX_ByteString& contents, + BCFORMAT format, + int32_t& outWidth, + int32_t& outHeight, + int32_t& e); + uint8_t* Encode(const CFX_ByteString& contents, + int32_t& outLength, + int32_t& e); + FX_BOOL CheckContentValidity(const CFX_WideStringC& contents); + CFX_WideString FilterContents(const CFX_WideStringC& contents); + FX_BOOL SetTextLocation(BC_TEXT_LOC location); + BC_TYPE GetType(); + + private: + FX_BOOL IsDigits(const CFX_ByteString& contents, + int32_t start, + int32_t length); + int32_t Encode128B(const CFX_ByteString& contents, CFX_PtrArray& patterns); + int32_t Encode128C(const CFX_ByteString& contents, CFX_PtrArray& patterns); + BC_TYPE m_codeFormat; + static const int32_t CODE_START_B; + static const int32_t CODE_START_C; + static const int32_t CODE_CODE_B; + static const int32_t CODE_CODE_C; + static const int32_t CODE_STOP; +}; + +#endif // XFA_FXBARCODE_ONED_BC_ONEDCODE128WRITER_H_ diff --git a/xfa/fxbarcode/oned/BC_OnedCode39Reader.cpp b/xfa/fxbarcode/oned/BC_OnedCode39Reader.cpp new file mode 100644 index 0000000000..e2f88e7a79 --- /dev/null +++ b/xfa/fxbarcode/oned/BC_OnedCode39Reader.cpp @@ -0,0 +1,287 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com +// Original code is licensed as follows: +/* + * Copyright 2008 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <algorithm> + +#include "xfa/fxbarcode/BC_Reader.h" +#include "xfa/fxbarcode/common/BC_CommonBitArray.h" +#include "xfa/fxbarcode/oned/BC_OneDReader.h" +#include "xfa/fxbarcode/oned/BC_OnedCode39Reader.h" +#include "xfa/fxbarcode/utils.h" + +const FX_CHAR* CBC_OnedCode39Reader::ALPHABET_STRING = + "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ-. *$/+%"; +const FX_CHAR* CBC_OnedCode39Reader::CHECKSUM_STRING = + "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ-. $/+%"; +const int32_t CBC_OnedCode39Reader::CHARACTER_ENCODINGS[44] = { + 0x034, 0x121, 0x061, 0x160, 0x031, 0x130, 0x070, 0x025, 0x124, + 0x064, 0x109, 0x049, 0x148, 0x019, 0x118, 0x058, 0x00D, 0x10C, + 0x04C, 0x01C, 0x103, 0x043, 0x142, 0x013, 0x112, 0x052, 0x007, + 0x106, 0x046, 0x016, 0x181, 0x0C1, 0x1C0, 0x091, 0x190, 0x0D0, + 0x085, 0x184, 0x0C4, 0x094, 0x0A8, 0x0A2, 0x08A, 0x02A}; +const int32_t CBC_OnedCode39Reader::ASTERISK_ENCODING = 0x094; + +CBC_OnedCode39Reader::CBC_OnedCode39Reader() + : m_usingCheckDigit(FALSE), m_extendedMode(FALSE) {} +CBC_OnedCode39Reader::CBC_OnedCode39Reader(FX_BOOL usingCheckDigit) + : m_usingCheckDigit(usingCheckDigit), m_extendedMode(FALSE) {} +CBC_OnedCode39Reader::CBC_OnedCode39Reader(FX_BOOL usingCheckDigit, + FX_BOOL extendedMode) + : m_usingCheckDigit(usingCheckDigit), m_extendedMode(extendedMode) {} +CBC_OnedCode39Reader::~CBC_OnedCode39Reader() {} +CFX_ByteString CBC_OnedCode39Reader::DecodeRow(int32_t rowNumber, + CBC_CommonBitArray* row, + int32_t hints, + int32_t& e) { + CFX_Int32Array* start = FindAsteriskPattern(row, e); + BC_EXCEPTION_CHECK_ReturnValue(e, ""); + int32_t nextStart = (*start)[1]; + delete start; + int32_t end = row->GetSize(); + while (nextStart < end && !row->Get(nextStart)) { + nextStart++; + } + CFX_ByteString result; + CFX_Int32Array counters; + counters.SetSize(9); + FX_CHAR decodedChar; + do { + RecordPattern(row, nextStart, &counters, e); + BC_EXCEPTION_CHECK_ReturnValue(e, ""); + int32_t pattern = ToNarrowWidePattern(&counters); + if (pattern < 0) { + e = BCExceptionNotFound; + return ""; + } + decodedChar = PatternToChar(pattern, e); + BC_EXCEPTION_CHECK_ReturnValue(e, ""); + result += decodedChar; + for (int32_t i = 0; i < counters.GetSize(); i++) { + nextStart += counters[i]; + } + while (nextStart < end && !row->Get(nextStart)) { + nextStart++; + } + } while (decodedChar != '*'); + result = result.Mid(0, result.GetLength() - 1); + int32_t lastPatternSize = 0; + for (int32_t j = 0; j < counters.GetSize(); j++) { + lastPatternSize += counters[j]; + } + if (m_usingCheckDigit) { + int32_t max = result.GetLength() - 1; + int32_t total = 0; + int32_t len = (int32_t)strlen(ALPHABET_STRING); + for (int32_t k = 0; k < max; k++) { + for (int32_t j = 0; j < len; j++) + if (ALPHABET_STRING[j] == result[k]) { + total += j; + } + } + if (result[max] != (ALPHABET_STRING)[total % 43]) { + e = BCExceptionChecksumException; + return ""; + } + result = result.Mid(0, result.GetLength() - 1); + } + if (result.GetLength() == 0) { + e = BCExceptionNotFound; + return ""; + } + if (m_extendedMode) { + CFX_ByteString bytestr = DecodeExtended(result, e); + BC_EXCEPTION_CHECK_ReturnValue(e, ""); + return bytestr; + } else { + return result; + } +} +CFX_Int32Array* CBC_OnedCode39Reader::FindAsteriskPattern( + CBC_CommonBitArray* row, + int32_t& e) { + int32_t width = row->GetSize(); + int32_t rowOffset = 0; + while (rowOffset < width) { + if (row->Get(rowOffset)) { + break; + } + rowOffset++; + } + int32_t counterPosition = 0; + CFX_Int32Array counters; + counters.SetSize(9); + int32_t patternStart = rowOffset; + FX_BOOL isWhite = FALSE; + int32_t patternLength = counters.GetSize(); + for (int32_t i = rowOffset; i < width; i++) { + FX_BOOL pixel = row->Get(i); + if (pixel ^ isWhite) { + counters[counterPosition]++; + } else { + if (counterPosition == patternLength - 1) { + if (ToNarrowWidePattern(&counters) == ASTERISK_ENCODING) { + FX_BOOL bT1 = + row->IsRange(std::max(0, patternStart - (i - patternStart) / 2), + patternStart, FALSE, e); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + if (bT1) { + CFX_Int32Array* result = new CFX_Int32Array; + result->SetSize(2); + (*result)[0] = patternStart; + (*result)[1] = i; + return result; + } + } + patternStart += counters[0] + counters[1]; + for (int32_t y = 2; y < patternLength; y++) { + counters[y - 2] = counters[y]; + } + counters[patternLength - 2] = 0; + counters[patternLength - 1] = 0; + counterPosition--; + } else { + counterPosition++; + } + counters[counterPosition] = 1; + isWhite = !isWhite; + } + } + e = BCExceptionNotFound; + return NULL; +} +int32_t CBC_OnedCode39Reader::ToNarrowWidePattern(CFX_Int32Array* counters) { + int32_t numCounters = counters->GetSize(); + int32_t maxNarrowCounter = 0; + int32_t wideCounters; + do { +#undef max + int32_t minCounter = FXSYS_IntMax; + for (int32_t i = 0; i < numCounters; i++) { + int32_t counter = (*counters)[i]; + if (counter < minCounter && counter > maxNarrowCounter) { + minCounter = counter; + } + } + maxNarrowCounter = minCounter; + wideCounters = 0; + int32_t totalWideCountersWidth = 0; + int32_t pattern = 0; + for (int32_t j = 0; j < numCounters; j++) { + int32_t counter = (*counters)[j]; + if ((*counters)[j] > maxNarrowCounter) { + pattern |= 1 << (numCounters - 1 - j); + wideCounters++; + totalWideCountersWidth += counter; + } + } + if (wideCounters == 3) { + for (int32_t k = 0; k < numCounters && wideCounters > 0; k++) { + int32_t counter = (*counters)[k]; + if ((*counters)[k] > maxNarrowCounter) { + wideCounters--; + if ((counter << 1) >= totalWideCountersWidth) { + return -1; + } + } + } + return pattern; + } + } while (wideCounters > 3); + return -1; +} +FX_CHAR CBC_OnedCode39Reader::PatternToChar(int32_t pattern, int32_t& e) { + for (int32_t i = 0; i < 44; i++) { + if (CHARACTER_ENCODINGS[i] == pattern) { + return (ALPHABET_STRING)[i]; + } + } + e = BCExceptionNotFound; + return 0; +} +CFX_ByteString CBC_OnedCode39Reader::DecodeExtended(CFX_ByteString& encoded, + int32_t& e) { + int32_t length = encoded.GetLength(); + CFX_ByteString decoded; + FX_CHAR c, next; + for (int32_t i = 0; i < length; i++) { + c = encoded[i]; + if (c == '+' || c == '$' || c == '%' || c == '/') { + next = encoded[i + 1]; + FX_CHAR decodedChar = '\0'; + switch (c) { + case '+': + if (next >= 'A' && next <= 'Z') { + decodedChar = (FX_CHAR)(next + 32); + } else { + e = BCExceptionFormatException; + return ""; + } + break; + case '$': + if (next >= 'A' && next <= 'Z') { + decodedChar = (FX_CHAR)(next - 64); + } else { + e = BCExceptionFormatException; + return ""; + } + break; + case '%': + if (next >= 'A' && next <= 'E') { + decodedChar = (FX_CHAR)(next - 38); + } else if (next >= 'F' && next <= 'J') { + decodedChar = (FX_CHAR)(next - 11); + } else if (next >= 'K' && next <= 'O' && next != 'M' && next != 'N') { + decodedChar = (FX_CHAR)(next + 16); + } else if (next >= 'P' && next <= 'S') { + decodedChar = (FX_CHAR)(next + 43); + } else if (next == 'U') { + decodedChar = (FX_CHAR)0; + } else if (next == 'V') { + decodedChar = (FX_CHAR)64; + } else if (next == 'W') { + decodedChar = (FX_CHAR)96; + } else if (next == 'T' || next == 'X' || next == 'Y' || next == 'Z') { + decodedChar = (FX_CHAR)127; + } else { + e = BCExceptionFormatException; + return ""; + } + break; + case '/': + if (next >= 'A' && next <= 'O') { + decodedChar = (FX_CHAR)(next - 32); + } else if (next == 'Z') { + decodedChar = ':'; + } else { + e = BCExceptionFormatException; + return ""; + } + break; + } + decoded += decodedChar; + i++; + } else { + decoded += c; + } + } + return decoded; +} diff --git a/xfa/fxbarcode/oned/BC_OnedCode39Reader.h b/xfa/fxbarcode/oned/BC_OnedCode39Reader.h new file mode 100644 index 0000000000..f1551e4761 --- /dev/null +++ b/xfa/fxbarcode/oned/BC_OnedCode39Reader.h @@ -0,0 +1,36 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef XFA_FXBARCODE_ONED_BC_ONEDCODE39READER_H_ +#define XFA_FXBARCODE_ONED_BC_ONEDCODE39READER_H_ + +class CBC_OneDReader; +class CBC_CommonBitArray; +class CBC_OnedCode39Reader : public CBC_OneDReader { + public: + static const FX_CHAR* ALPHABET_STRING; + static const FX_CHAR* CHECKSUM_STRING; + static const int32_t CHARACTER_ENCODINGS[44]; + static const int32_t ASTERISK_ENCODING; + CBC_OnedCode39Reader(); + CBC_OnedCode39Reader(FX_BOOL usingCheckDigit); + CBC_OnedCode39Reader(FX_BOOL usingCheckDigit, FX_BOOL extendedMode); + virtual ~CBC_OnedCode39Reader(); + CFX_ByteString DecodeRow(int32_t rowNumber, + CBC_CommonBitArray* row, + int32_t hints, + int32_t& e); + + private: + FX_BOOL m_usingCheckDigit; + FX_BOOL m_extendedMode; + CFX_Int32Array* FindAsteriskPattern(CBC_CommonBitArray* row, int32_t& e); + int32_t ToNarrowWidePattern(CFX_Int32Array* counters); + FX_CHAR PatternToChar(int32_t pattern, int32_t& e); + CFX_ByteString DecodeExtended(CFX_ByteString& encoded, int32_t& e); +}; + +#endif // XFA_FXBARCODE_ONED_BC_ONEDCODE39READER_H_ diff --git a/xfa/fxbarcode/oned/BC_OnedCode39Writer.cpp b/xfa/fxbarcode/oned/BC_OnedCode39Writer.cpp new file mode 100644 index 0000000000..31e75ca7df --- /dev/null +++ b/xfa/fxbarcode/oned/BC_OnedCode39Writer.cpp @@ -0,0 +1,364 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com +// Original code is licensed as follows: +/* + * Copyright 2010 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "xfa/fxbarcode/BC_Reader.h" +#include "xfa/fxbarcode/BC_Writer.h" +#include "xfa/fxbarcode/common/BC_CommonBitMatrix.h" +#include "xfa/fxbarcode/oned/BC_OneDReader.h" +#include "xfa/fxbarcode/oned/BC_OneDimWriter.h" +#include "xfa/fxbarcode/oned/BC_OnedCode39Reader.h" +#include "xfa/fxbarcode/oned/BC_OnedCode39Writer.h" + +CBC_OnedCode39Writer::CBC_OnedCode39Writer() { + m_extendedMode = FALSE; + m_iWideNarrRatio = 3; +} +CBC_OnedCode39Writer::CBC_OnedCode39Writer(FX_BOOL extendedMode) { + m_iWideNarrRatio = 3; + m_extendedMode = extendedMode; +} +CBC_OnedCode39Writer::~CBC_OnedCode39Writer() {} +FX_BOOL CBC_OnedCode39Writer::CheckContentValidity( + const CFX_WideStringC& contents) { + if (m_extendedMode) { + return CheckExtendedContentValidity(contents); + } + for (int32_t i = 0; i < contents.GetLength(); i++) { + FX_WCHAR ch = contents.GetAt(i); + if ((ch >= (FX_WCHAR)'0' && ch <= (FX_WCHAR)'9') || + (ch >= (FX_WCHAR)'A' && ch <= (FX_WCHAR)'Z') || ch == (FX_WCHAR)'-' || + ch == (FX_WCHAR)'.' || ch == (FX_WCHAR)' ' || ch == (FX_WCHAR)'*' || + ch == (FX_WCHAR)'$' || ch == (FX_WCHAR)'/' || ch == (FX_WCHAR)'+' || + ch == (FX_WCHAR)'%') { + continue; + } + return FALSE; + } + return TRUE; +} +FX_BOOL CBC_OnedCode39Writer::CheckExtendedContentValidity( + const CFX_WideStringC& contents) { + for (int32_t i = 0; i < contents.GetLength(); i++) { + FX_WCHAR ch = contents.GetAt(i); + if (ch > 127) { + return FALSE; + } + } + return TRUE; +} +CFX_WideString CBC_OnedCode39Writer::FilterContents( + const CFX_WideStringC& contents) { + if (m_extendedMode) { + return FilterExtendedContents(contents); + } + CFX_WideString filtercontents; + for (int32_t i = 0; i < contents.GetLength(); i++) { + FX_WCHAR ch = contents.GetAt(i); + if (ch == (FX_WCHAR)'*' && (i == 0 || i == contents.GetLength() - 1)) { + continue; + } + if (ch > 175) { + i++; + continue; + } else { + ch = Upper(ch); + } + if ((ch >= (FX_WCHAR)'0' && ch <= (FX_WCHAR)'9') || + (ch >= (FX_WCHAR)'A' && ch <= (FX_WCHAR)'Z') || ch == (FX_WCHAR)'-' || + ch == (FX_WCHAR)'.' || ch == (FX_WCHAR)' ' || ch == (FX_WCHAR)'*' || + ch == (FX_WCHAR)'$' || ch == (FX_WCHAR)'/' || ch == (FX_WCHAR)'+' || + ch == (FX_WCHAR)'%') { + filtercontents += ch; + } + } + return filtercontents; +} +CFX_WideString CBC_OnedCode39Writer::FilterExtendedContents( + const CFX_WideStringC& contents) { + CFX_WideString filtercontents; + for (int32_t i = 0; i < contents.GetLength(); i++) { + FX_WCHAR ch = contents.GetAt(i); + if (ch == (FX_WCHAR)'*' && (i == 0 || i == contents.GetLength() - 1)) { + continue; + } + if (ch > 175) { + i++; + continue; + } + if (ch > 127 && ch < 176) { + continue; + } + if (ch == 0) { + filtercontents += '%'; + filtercontents += 'U'; + } else if (ch >= 1 && ch <= 26) { + filtercontents += '$'; + filtercontents += (ch + 64); + } else if (ch >= 27 && ch <= 31) { + filtercontents += '%'; + filtercontents += (ch + 38); + } else if (ch >= 33 && ch <= 47 && ch != 45 && ch != 46) { + filtercontents += '/'; + filtercontents += (ch + 32); + } else if (ch == 58) { + filtercontents += '/'; + filtercontents += 'Z'; + } else if (ch >= 59 && ch <= 63) { + filtercontents += '%'; + filtercontents += ch + 11; + } else if (ch == 64) { + filtercontents += '%'; + filtercontents += 'V'; + } else if (ch >= 91 && ch <= 95) { + filtercontents += '%'; + filtercontents += ch - 16; + } else if (ch == 96) { + filtercontents += '%'; + filtercontents += 'W'; + } else if (ch >= 97 && ch <= 122) { + filtercontents += '+'; + filtercontents += ch - 32; + } else if (ch >= 123 && ch <= 126) { + filtercontents += '%'; + filtercontents += ch - 43; + } else if (ch == 127) { + filtercontents += '%'; + filtercontents += 'T'; + } else { + filtercontents += ch; + } + } + return filtercontents; +} +CFX_WideString CBC_OnedCode39Writer::RenderTextContents( + const CFX_WideStringC& contents) { + if (m_extendedMode) { + return RenderExtendedTextContents(contents); + } + CFX_WideString renderContents; + for (int32_t i = 0; i < contents.GetLength(); i++) { + FX_WCHAR ch = contents.GetAt(i); + if (ch == (FX_WCHAR)'*' && (i == 0 || i == contents.GetLength() - 1)) { + continue; + } + if (ch > 175) { + i++; + continue; + } + if ((ch >= (FX_WCHAR)'0' && ch <= (FX_WCHAR)'9') || + (ch >= (FX_WCHAR)'A' && ch <= (FX_WCHAR)'Z') || + (ch >= (FX_WCHAR)'a' && ch <= (FX_WCHAR)'z') || ch == (FX_WCHAR)'-' || + ch == (FX_WCHAR)'.' || ch == (FX_WCHAR)' ' || ch == (FX_WCHAR)'*' || + ch == (FX_WCHAR)'$' || ch == (FX_WCHAR)'/' || ch == (FX_WCHAR)'+' || + ch == (FX_WCHAR)'%') { + renderContents += ch; + } + } + return renderContents; +} +CFX_WideString CBC_OnedCode39Writer::RenderExtendedTextContents( + const CFX_WideStringC& contents) { + CFX_WideString renderContents; + for (int32_t i = 0; i < contents.GetLength(); i++) { + FX_WCHAR ch = contents.GetAt(i); + if (ch == (FX_WCHAR)'*' && (i == 0 || i == contents.GetLength() - 1)) { + continue; + } + if (ch > 175) { + i++; + continue; + } + if (ch > 127 && ch < 176) { + continue; + } + renderContents += ch; + } + return renderContents; +} +FX_BOOL CBC_OnedCode39Writer::SetTextLocation(BC_TEXT_LOC location) { + if (location < BC_TEXT_LOC_NONE || location > BC_TEXT_LOC_BELOWEMBED) { + return FALSE; + } + m_locTextLoc = location; + return TRUE; +} +FX_BOOL CBC_OnedCode39Writer::SetWideNarrowRatio(int32_t ratio) { + if (ratio < 2 || ratio > 3) { + return FALSE; + } + m_iWideNarrRatio = ratio; + return TRUE; +} +uint8_t* CBC_OnedCode39Writer::Encode(const CFX_ByteString& contents, + BCFORMAT format, + int32_t& outWidth, + int32_t& outHeight, + int32_t& e) { + uint8_t* ret = Encode(contents, format, outWidth, outHeight, 0, e); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + return ret; +} +uint8_t* CBC_OnedCode39Writer::Encode(const CFX_ByteString& contents, + BCFORMAT format, + int32_t& outWidth, + int32_t& outHeight, + int32_t hints, + int32_t& e) { + if (format != BCFORMAT_CODE_39) { + e = BCExceptionOnlyEncodeCODE_39; + return NULL; + } + uint8_t* ret = + CBC_OneDimWriter::Encode(contents, format, outWidth, outHeight, hints, e); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + return ret; +} +void CBC_OnedCode39Writer::ToIntArray(int32_t a, int32_t* toReturn) { + for (int32_t i = 0; i < 9; i++) { + toReturn[i] = (a & (1 << i)) == 0 ? 1 : m_iWideNarrRatio; + } +} +FX_CHAR CBC_OnedCode39Writer::CalcCheckSum(const CFX_ByteString& contents, + int32_t& e) { + int32_t length = contents.GetLength(); + if (length > 80) { + e = BCExceptionContentsLengthShouldBetween1and80; + return '*'; + } + int32_t checksum = 0; + int32_t len = (int32_t)strlen(CBC_OnedCode39Reader::ALPHABET_STRING); + for (int32_t i = 0; i < contents.GetLength(); i++) { + int32_t j = 0; + for (; j < len; j++) { + if (CBC_OnedCode39Reader::ALPHABET_STRING[j] == contents[i]) { + if (contents[i] != '*') { + checksum += j; + break; + } else { + break; + } + } + } + if (j >= len) { + e = BCExceptionUnSupportedString; + return '*'; + } + } + checksum = checksum % 43; + return CBC_OnedCode39Reader::CHECKSUM_STRING[checksum]; +} +uint8_t* CBC_OnedCode39Writer::Encode(const CFX_ByteString& contents, + int32_t& outlength, + int32_t& e) { + FX_CHAR checksum = CalcCheckSum(contents, e); + if (checksum == '*') { + return NULL; + } + int32_t widths[9] = {0}; + int32_t wideStrideNum = 3; + int32_t narrStrideNum = 9 - wideStrideNum; + CFX_ByteString encodedContents = contents; + if (m_bCalcChecksum) { + encodedContents += checksum; + } + m_iContentLen = encodedContents.GetLength(); + int32_t codeWidth = (wideStrideNum * m_iWideNarrRatio + narrStrideNum) * 2 + + 1 + m_iContentLen; + int32_t len = (int32_t)strlen(CBC_OnedCode39Reader::ALPHABET_STRING); + for (int32_t j = 0; j < m_iContentLen; j++) { + for (int32_t i = 0; i < len; i++) { + if (CBC_OnedCode39Reader::ALPHABET_STRING[i] == encodedContents[j]) { + ToIntArray(CBC_OnedCode39Reader::CHARACTER_ENCODINGS[i], widths); + for (int32_t k = 0; k < 9; k++) { + codeWidth += widths[k]; + } + } + } + } + outlength = codeWidth; + uint8_t* result = FX_Alloc(uint8_t, codeWidth); + ToIntArray(CBC_OnedCode39Reader::CHARACTER_ENCODINGS[39], widths); + int32_t pos = AppendPattern(result, 0, widths, 9, 1, e); + if (e != BCExceptionNO) { + FX_Free(result); + return NULL; + } + int32_t narrowWhite[] = {1}; + pos += AppendPattern(result, pos, narrowWhite, 1, 0, e); + if (e != BCExceptionNO) { + FX_Free(result); + return NULL; + } + for (int32_t l = m_iContentLen - 1; l >= 0; l--) { + for (int32_t i = 0; i < len; i++) { + if (CBC_OnedCode39Reader::ALPHABET_STRING[i] == encodedContents[l]) { + ToIntArray(CBC_OnedCode39Reader::CHARACTER_ENCODINGS[i], widths); + pos += AppendPattern(result, pos, widths, 9, 1, e); + if (e != BCExceptionNO) { + FX_Free(result); + return NULL; + } + } + } + pos += AppendPattern(result, pos, narrowWhite, 1, 0, e); + if (e != BCExceptionNO) { + FX_Free(result); + return NULL; + } + } + ToIntArray(CBC_OnedCode39Reader::CHARACTER_ENCODINGS[39], widths); + pos += AppendPattern(result, pos, widths, 9, 1, e); + if (e != BCExceptionNO) { + FX_Free(result); + return NULL; + } + for (int32_t i = 0; i < codeWidth / 2; i++) { + result[i] ^= result[codeWidth - 1 - i]; + result[codeWidth - 1 - i] ^= result[i]; + result[i] ^= result[codeWidth - 1 - i]; + } + return result; +} +CFX_WideString CBC_OnedCode39Writer::encodedContents( + const CFX_WideStringC& contents, + int32_t& e) { + CFX_WideString encodedContents = contents; + if (m_bCalcChecksum && m_bPrintChecksum) { + CFX_WideString checksumContent = FilterContents(contents); + CFX_ByteString str = checksumContent.UTF8Encode(); + FX_CHAR checksum; + checksum = CalcCheckSum(str, e); + BC_EXCEPTION_CHECK_ReturnValue(e, FX_WSTRC(L"")); + str += checksum; + encodedContents += checksum; + } + return encodedContents; +} +void CBC_OnedCode39Writer::RenderResult(const CFX_WideStringC& contents, + uint8_t* code, + int32_t codeLength, + FX_BOOL isDevice, + int32_t& e) { + CFX_WideString encodedCon = encodedContents(contents, e); + BC_EXCEPTION_CHECK_ReturnVoid(e); + CBC_OneDimWriter::RenderResult(encodedCon, code, codeLength, isDevice, e); +} diff --git a/xfa/fxbarcode/oned/BC_OnedCode39Writer.h b/xfa/fxbarcode/oned/BC_OnedCode39Writer.h new file mode 100644 index 0000000000..b438727130 --- /dev/null +++ b/xfa/fxbarcode/oned/BC_OnedCode39Writer.h @@ -0,0 +1,53 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef XFA_FXBARCODE_ONED_BC_ONEDCODE39WRITER_H_ +#define XFA_FXBARCODE_ONED_BC_ONEDCODE39WRITER_H_ + +enum BC_TEXT_LOC; +class CBC_OneDimWriter; +class CBC_OnedCode39Writer : public CBC_OneDimWriter { + public: + CBC_OnedCode39Writer(); + CBC_OnedCode39Writer(FX_BOOL extendedMode); + virtual ~CBC_OnedCode39Writer(); + uint8_t* Encode(const CFX_ByteString& contents, + BCFORMAT format, + int32_t& outWidth, + int32_t& outHeight, + int32_t& e); + uint8_t* Encode(const CFX_ByteString& contents, + BCFORMAT format, + int32_t& outWidth, + int32_t& outHeight, + int32_t hints, + int32_t& e); + uint8_t* Encode(const CFX_ByteString& contents, + int32_t& outLength, + int32_t& e); + void RenderResult(const CFX_WideStringC& contents, + uint8_t* code, + int32_t codeLength, + FX_BOOL isDevice, + int32_t& e); + CFX_WideString encodedContents(const CFX_WideStringC& contents, int32_t& e); + FX_BOOL CheckContentValidity(const CFX_WideStringC& contents); + FX_BOOL CheckExtendedContentValidity(const CFX_WideStringC& contents); + CFX_WideString FilterContents(const CFX_WideStringC& contents); + CFX_WideString FilterExtendedContents(const CFX_WideStringC& contents); + CFX_WideString RenderTextContents(const CFX_WideStringC& contents); + CFX_WideString RenderExtendedTextContents(const CFX_WideStringC& contents); + FX_BOOL SetTextLocation(BC_TEXT_LOC loction); + FX_BOOL SetWideNarrowRatio(int32_t ratio); + + private: + void ToIntArray(int32_t a, int32_t* toReturn); + FX_CHAR CalcCheckSum(const CFX_ByteString& contents, int32_t& e); + int32_t m_iWideNarrRatio; + FX_BOOL m_extendedMode; +}; + +#endif // XFA_FXBARCODE_ONED_BC_ONEDCODE39WRITER_H_ diff --git a/xfa/fxbarcode/oned/BC_OnedEAN13Reader.cpp b/xfa/fxbarcode/oned/BC_OnedEAN13Reader.cpp new file mode 100644 index 0000000000..83fea7d5f2 --- /dev/null +++ b/xfa/fxbarcode/oned/BC_OnedEAN13Reader.cpp @@ -0,0 +1,96 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com +// Original code is licensed as follows: +/* + * Copyright 2008 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "xfa/fxbarcode/BC_Reader.h" +#include "xfa/fxbarcode/common/BC_CommonBitArray.h" +#include "xfa/fxbarcode/oned/BC_OneDReader.h" +#include "xfa/fxbarcode/oned/BC_OneDimReader.h" +#include "xfa/fxbarcode/oned/BC_OnedEAN13Reader.h" +#include "xfa/fxbarcode/utils.h" + +const int32_t CBC_OnedEAN13Reader::FIRST_DIGIT_ENCODINGS[10] = { + 0x00, 0x0B, 0x0D, 0xE, 0x13, 0x19, 0x1C, 0x15, 0x16, 0x1A}; + +CBC_OnedEAN13Reader::CBC_OnedEAN13Reader() {} +CBC_OnedEAN13Reader::~CBC_OnedEAN13Reader() {} +void CBC_OnedEAN13Reader::DetermineFirstDigit(CFX_ByteString& result, + int32_t lgPatternFound, + int32_t& e) { + for (int32_t d = 0; d < 10; d++) { + if (lgPatternFound == FIRST_DIGIT_ENCODINGS[d]) { + result.Insert(0, (FX_CHAR)('0' + d)); + return; + } + } + e = BCExceptionNotFound; + BC_EXCEPTION_CHECK_ReturnVoid(e); +} +int32_t CBC_OnedEAN13Reader::DecodeMiddle(CBC_CommonBitArray* row, + CFX_Int32Array* startRange, + CFX_ByteString& resultString, + int32_t& e) { + CFX_Int32Array counters; + counters.Add(0); + counters.Add(0); + counters.Add(0); + counters.Add(0); + int32_t end = row->GetSize(); + int32_t rowOffset = (*startRange)[1]; + int32_t lgPatternFound = 0; + for (int32_t x = 0; x < 6 && rowOffset < end; x++) { + int32_t bestMatch = + DecodeDigit(row, &counters, rowOffset, + &(CBC_OneDimReader::L_AND_G_PATTERNS[0][0]), 20, e); + BC_EXCEPTION_CHECK_ReturnValue(e, 0); + resultString += (FX_CHAR)('0' + bestMatch % 10); + for (int32_t i = 0; i < counters.GetSize(); i++) { + rowOffset += counters[i]; + } + if (bestMatch >= 10) { + lgPatternFound |= 1 << (5 - x); + } + } + DetermineFirstDigit(resultString, lgPatternFound, e); + BC_EXCEPTION_CHECK_ReturnValue(e, 0); + CFX_Int32Array result; + result.Add(CBC_OneDimReader::MIDDLE_PATTERN[0]); + result.Add(CBC_OneDimReader::MIDDLE_PATTERN[1]); + result.Add(CBC_OneDimReader::MIDDLE_PATTERN[2]); + result.Add(CBC_OneDimReader::MIDDLE_PATTERN[3]); + result.Add(CBC_OneDimReader::MIDDLE_PATTERN[4]); + CFX_Int32Array* middleRange = + FindGuardPattern(row, rowOffset, TRUE, &result, e); + BC_EXCEPTION_CHECK_ReturnValue(e, 0); + rowOffset = (*middleRange)[1]; + delete middleRange; + for (int32_t Y = 0; Y < 6 && rowOffset < end; Y++) { + int32_t bestMatch = + DecodeDigit(row, &counters, rowOffset, + &(CBC_OneDimReader::L_PATTERNS[0][0]), 10, e); + BC_EXCEPTION_CHECK_ReturnValue(e, 0); + resultString += (FX_CHAR)('0' + bestMatch); + for (int32_t k = 0; k < counters.GetSize(); k++) { + rowOffset += counters[k]; + } + } + return rowOffset; +} diff --git a/xfa/fxbarcode/oned/BC_OnedEAN13Reader.h b/xfa/fxbarcode/oned/BC_OnedEAN13Reader.h new file mode 100644 index 0000000000..0d9d614901 --- /dev/null +++ b/xfa/fxbarcode/oned/BC_OnedEAN13Reader.h @@ -0,0 +1,31 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef XFA_FXBARCODE_ONED_BC_ONEDEAN13READER_H_ +#define XFA_FXBARCODE_ONED_BC_ONEDEAN13READER_H_ +class CBC_OneDimReader; +class CBC_CommonBitArray; +class CBC_OnedEAN13Reader; +class CBC_OnedEAN13Reader : public CBC_OneDimReader { + public: + static const int32_t FIRST_DIGIT_ENCODINGS[10]; + CBC_OnedEAN13Reader(); + virtual ~CBC_OnedEAN13Reader(); + + private: + void DetermineFirstDigit(CFX_ByteString& result, + int32_t lgPatternFound, + int32_t& e); + + protected: + int32_t DecodeMiddle(CBC_CommonBitArray* row, + CFX_Int32Array* startRange, + CFX_ByteString& resultString, + int32_t& e); + friend class CBC_OnedUPCAReader; +}; + +#endif // XFA_FXBARCODE_ONED_BC_ONEDEAN13READER_H_ diff --git a/xfa/fxbarcode/oned/BC_OnedEAN13Writer.cpp b/xfa/fxbarcode/oned/BC_OnedEAN13Writer.cpp new file mode 100644 index 0000000000..b534602fb3 --- /dev/null +++ b/xfa/fxbarcode/oned/BC_OnedEAN13Writer.cpp @@ -0,0 +1,301 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com +// Original code is licensed as follows: +/* + * Copyright 2009 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "xfa/fxbarcode/BC_Reader.h" +#include "xfa/fxbarcode/BC_Writer.h" +#include "xfa/fxbarcode/oned/BC_OneDReader.h" +#include "xfa/fxbarcode/oned/BC_OneDimReader.h" +#include "xfa/fxbarcode/oned/BC_OneDimWriter.h" +#include "xfa/fxbarcode/oned/BC_OnedEAN13Reader.h" +#include "xfa/fxbarcode/oned/BC_OnedEAN13Writer.h" + +CBC_OnedEAN13Writer::CBC_OnedEAN13Writer() { + m_bLeftPadding = TRUE; + m_codeWidth = 3 + (7 * 6) + 5 + (7 * 6) + 3; +} +CBC_OnedEAN13Writer::~CBC_OnedEAN13Writer() {} +FX_BOOL CBC_OnedEAN13Writer::CheckContentValidity( + const CFX_WideStringC& contents) { + for (int32_t i = 0; i < contents.GetLength(); i++) { + if (contents.GetAt(i) >= '0' && contents.GetAt(i) <= '9') { + continue; + } else { + return FALSE; + } + } + return TRUE; +} +CFX_WideString CBC_OnedEAN13Writer::FilterContents( + const CFX_WideStringC& contents) { + CFX_WideString filtercontents; + FX_WCHAR ch; + for (int32_t i = 0; i < contents.GetLength(); i++) { + ch = contents.GetAt(i); + if (ch > 175) { + i++; + continue; + } + if (ch >= '0' && ch <= '9') { + filtercontents += ch; + } + } + return filtercontents; +} +int32_t CBC_OnedEAN13Writer::CalcChecksum(const CFX_ByteString& contents) { + int32_t odd = 0; + int32_t even = 0; + int32_t j = 1; + for (int32_t i = contents.GetLength() - 1; i >= 0; i--) { + if (j % 2) { + odd += FXSYS_atoi(contents.Mid(i, 1)); + } else { + even += FXSYS_atoi(contents.Mid(i, 1)); + } + j++; + } + int32_t checksum = (odd * 3 + even) % 10; + checksum = (10 - checksum) % 10; + return (checksum); +} +uint8_t* CBC_OnedEAN13Writer::Encode(const CFX_ByteString& contents, + BCFORMAT format, + int32_t& outWidth, + int32_t& outHeight, + int32_t& e) { + uint8_t* ret = Encode(contents, format, outWidth, outHeight, 0, e); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + return ret; +} +uint8_t* CBC_OnedEAN13Writer::Encode(const CFX_ByteString& contents, + BCFORMAT format, + int32_t& outWidth, + int32_t& outHeight, + int32_t hints, + int32_t& e) { + if (format != BCFORMAT_EAN_13) { + e = BCExceptionOnlyEncodeEAN_13; + } + uint8_t* ret = + CBC_OneDimWriter::Encode(contents, format, outWidth, outHeight, hints, e); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + return ret; +} +uint8_t* CBC_OnedEAN13Writer::Encode(const CFX_ByteString& contents, + int32_t& outLength, + int32_t& e) { + if (contents.GetLength() != 13) { + e = BCExceptionDigitLengthShould13; + return NULL; + } + m_iDataLenth = 13; + int32_t firstDigit = FXSYS_atoi(contents.Mid(0, 1)); + int32_t parities = CBC_OnedEAN13Reader::FIRST_DIGIT_ENCODINGS[firstDigit]; + outLength = m_codeWidth; + uint8_t* result = FX_Alloc(uint8_t, m_codeWidth); + int32_t pos = 0; + pos += + AppendPattern(result, pos, CBC_OneDimReader::START_END_PATTERN, 3, 1, e); + if (e != BCExceptionNO) { + FX_Free(result); + return NULL; + } + int32_t i = 0; + for (i = 1; i <= 6; i++) { + int32_t digit = FXSYS_atoi(contents.Mid(i, 1)); + if ((parities >> (6 - i) & 1) == 1) { + digit += 10; + } + pos += AppendPattern(result, pos, CBC_OneDimReader::L_AND_G_PATTERNS[digit], + 4, 0, e); + if (e != BCExceptionNO) { + FX_Free(result); + return NULL; + } + } + pos += AppendPattern(result, pos, CBC_OneDimReader::MIDDLE_PATTERN, 5, 0, e); + if (e != BCExceptionNO) { + FX_Free(result); + return NULL; + } + for (i = 7; i <= 12; i++) { + int32_t digit = FXSYS_atoi(contents.Mid(i, 1)); + pos += AppendPattern(result, pos, CBC_OneDimReader::L_PATTERNS[digit], 4, 1, + e); + if (e != BCExceptionNO) { + FX_Free(result); + return NULL; + } + } + pos += + AppendPattern(result, pos, CBC_OneDimReader::START_END_PATTERN, 3, 1, e); + if (e != BCExceptionNO) { + FX_Free(result); + return NULL; + } + return result; +} +void CBC_OnedEAN13Writer::ShowChars(const CFX_WideStringC& contents, + CFX_DIBitmap* pOutBitmap, + CFX_RenderDevice* device, + const CFX_Matrix* matrix, + int32_t barWidth, + int32_t multiple, + int32_t& e) { + if (device == NULL && pOutBitmap == NULL) { + e = BCExceptionIllegalArgument; + return; + } + int32_t leftPadding = 7 * multiple; + int32_t leftPosition = 3 * multiple + leftPadding; + CFX_ByteString str = FX_UTF8Encode(contents); + int32_t iLen = str.GetLength(); + FXTEXT_CHARPOS* pCharPos = FX_Alloc(FXTEXT_CHARPOS, iLen); + FXSYS_memset(pCharPos, 0, sizeof(FXTEXT_CHARPOS) * iLen); + CFX_FxgeDevice geBitmap; + if (pOutBitmap) { + geBitmap.Attach(pOutBitmap); + } + int32_t iFontSize = (int32_t)fabs(m_fFontSize); + int32_t iTextHeight = iFontSize + 1; + CFX_ByteString tempStr = str.Mid(1, 6); + int32_t strWidth = multiple * 42; + if (pOutBitmap == NULL) { + CFX_Matrix matr(m_outputHScale, 0.0, 0.0, 1.0, 0.0, 0.0); + CFX_FloatRect rect( + (FX_FLOAT)leftPosition, (FX_FLOAT)(m_Height - iTextHeight), + (FX_FLOAT)(leftPosition + strWidth - 0.5), (FX_FLOAT)m_Height); + matr.Concat(*matrix); + matr.TransformRect(rect); + FX_RECT re = rect.GetOutterRect(); + device->FillRect(&re, m_backgroundColor); + CFX_FloatRect rect1( + (FX_FLOAT)(leftPosition + 47 * multiple), + (FX_FLOAT)(m_Height - iTextHeight), + (FX_FLOAT)(leftPosition + 47 * multiple + strWidth - 0.5), + (FX_FLOAT)m_Height); + CFX_Matrix matr1(m_outputHScale, 0.0, 0.0, 1.0, 0.0, 0.0); + matr1.Concat(*matrix); + matr1.TransformRect(rect1); + re = rect1.GetOutterRect(); + device->FillRect(&re, m_backgroundColor); + int32_t strWidth1 = multiple * 7; + CFX_Matrix matr2(m_outputHScale, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f); + CFX_FloatRect rect2(0.0f, (FX_FLOAT)(m_Height - iTextHeight), + (FX_FLOAT)strWidth1 - 0.5f, (FX_FLOAT)m_Height); + matr2.Concat(*matrix); + matr2.TransformRect(rect2); + re = rect2.GetOutterRect(); + device->FillRect(&re, m_backgroundColor); + } + FX_FLOAT blank = 0.0; + iLen = tempStr.GetLength(); + if (pOutBitmap == NULL) { + strWidth = (int32_t)(strWidth * m_outputHScale); + } + CalcTextInfo(tempStr, pCharPos + 1, m_pFont, (FX_FLOAT)strWidth, iFontSize, + blank); + CFX_Matrix affine_matrix(1.0, 0.0, 0.0, -1.0, 0.0, (FX_FLOAT)iFontSize); + CFX_FxgeDevice ge; + if (pOutBitmap) { + ge.Create(strWidth, iTextHeight, FXDIB_Argb); + FX_RECT rect(0, 0, strWidth, iTextHeight); + ge.FillRect(&rect, m_backgroundColor); + ge.DrawNormalText(iLen, pCharPos + 1, m_pFont, + CFX_GEModule::Get()->GetFontCache(), (FX_FLOAT)iFontSize, + (CFX_Matrix*)&affine_matrix, m_fontColor, + FXTEXT_CLEARTYPE); + geBitmap.SetDIBits(ge.GetBitmap(), leftPosition, m_Height - iTextHeight); + } else { + CFX_Matrix affine_matrix1(1.0, 0.0, 0.0, -1.0, + (FX_FLOAT)leftPosition * m_outputHScale, + (FX_FLOAT)(m_Height - iTextHeight) + iFontSize); + if (matrix) { + affine_matrix1.Concat(*matrix); + } + device->DrawNormalText(iLen, pCharPos + 1, m_pFont, + CFX_GEModule::Get()->GetFontCache(), + (FX_FLOAT)iFontSize, (CFX_Matrix*)&affine_matrix1, + m_fontColor, FXTEXT_CLEARTYPE); + } + tempStr = str.Mid(7, 6); + iLen = tempStr.GetLength(); + CalcTextInfo(tempStr, pCharPos + 7, m_pFont, (FX_FLOAT)strWidth, iFontSize, + blank); + if (pOutBitmap) { + FX_RECT rect1(0, 0, strWidth, iTextHeight); + ge.FillRect(&rect1, m_backgroundColor); + ge.DrawNormalText(iLen, pCharPos + 7, m_pFont, + CFX_GEModule::Get()->GetFontCache(), (FX_FLOAT)iFontSize, + (CFX_Matrix*)&affine_matrix, m_fontColor, + FXTEXT_CLEARTYPE); + geBitmap.SetDIBits(ge.GetBitmap(), leftPosition + 47 * multiple, + m_Height - iTextHeight); + } else { + CFX_Matrix affine_matrix1( + 1.0, 0.0, 0.0, -1.0, + (FX_FLOAT)(leftPosition + 47 * multiple) * m_outputHScale, + (FX_FLOAT)(m_Height - iTextHeight + iFontSize)); + if (matrix) { + affine_matrix1.Concat(*matrix); + } + device->DrawNormalText(iLen, pCharPos + 7, m_pFont, + CFX_GEModule::Get()->GetFontCache(), + (FX_FLOAT)iFontSize, (CFX_Matrix*)&affine_matrix1, + m_fontColor, FXTEXT_CLEARTYPE); + } + tempStr = str.Mid(0, 1); + iLen = tempStr.GetLength(); + strWidth = multiple * 7; + if (pOutBitmap == NULL) { + strWidth = (int32_t)(strWidth * m_outputHScale); + } + CalcTextInfo(tempStr, pCharPos, m_pFont, (FX_FLOAT)strWidth, iFontSize, + blank); + if (pOutBitmap) { + delete ge.GetBitmap(); + ge.Create(strWidth, iTextHeight, FXDIB_Argb); + ge.GetBitmap()->Clear(m_backgroundColor); + ge.DrawNormalText(iLen, pCharPos, m_pFont, + CFX_GEModule::Get()->GetFontCache(), (FX_FLOAT)iFontSize, + (CFX_Matrix*)&affine_matrix, m_fontColor, + FXTEXT_CLEARTYPE); + geBitmap.SetDIBits(ge.GetBitmap(), 0, m_Height - iTextHeight); + } else { + CFX_Matrix affine_matrix1(1.0, 0.0, 0.0, -1.0, 0.0, + (FX_FLOAT)(m_Height - iTextHeight + iFontSize)); + if (matrix) { + affine_matrix1.Concat(*matrix); + } + device->DrawNormalText(iLen, pCharPos, m_pFont, + CFX_GEModule::Get()->GetFontCache(), + (FX_FLOAT)iFontSize, (CFX_Matrix*)&affine_matrix1, + m_fontColor, FXTEXT_CLEARTYPE); + } + FX_Free(pCharPos); +} +void CBC_OnedEAN13Writer::RenderResult(const CFX_WideStringC& contents, + uint8_t* code, + int32_t codeLength, + FX_BOOL isDevice, + int32_t& e) { + CBC_OneDimWriter::RenderResult(contents, code, codeLength, isDevice, e); +} diff --git a/xfa/fxbarcode/oned/BC_OnedEAN13Writer.h b/xfa/fxbarcode/oned/BC_OnedEAN13Writer.h new file mode 100644 index 0000000000..fd23129975 --- /dev/null +++ b/xfa/fxbarcode/oned/BC_OnedEAN13Writer.h @@ -0,0 +1,53 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef XFA_FXBARCODE_ONED_BC_ONEDEAN13WRITER_H_ +#define XFA_FXBARCODE_ONED_BC_ONEDEAN13WRITER_H_ + +class CBC_OneDimWriter; +class CBC_OnedEAN13Writer; +class CBC_OnedEAN13Writer : public CBC_OneDimWriter { + private: + int32_t m_codeWidth; + + public: + CBC_OnedEAN13Writer(); + virtual ~CBC_OnedEAN13Writer(); + + uint8_t* Encode(const CFX_ByteString& contents, + BCFORMAT format, + int32_t& outWidth, + int32_t& outHeight, + int32_t& e); + uint8_t* Encode(const CFX_ByteString& contents, + BCFORMAT format, + int32_t& outWidth, + int32_t& outHeight, + int32_t hints, + int32_t& e); + uint8_t* Encode(const CFX_ByteString& contents, + int32_t& outLength, + int32_t& e); + void RenderResult(const CFX_WideStringC& contents, + uint8_t* code, + int32_t codeLength, + FX_BOOL isDevice, + int32_t& e); + FX_BOOL CheckContentValidity(const CFX_WideStringC& contents); + CFX_WideString FilterContents(const CFX_WideStringC& contents); + int32_t CalcChecksum(const CFX_ByteString& contents); + + protected: + void ShowChars(const CFX_WideStringC& contents, + CFX_DIBitmap* pOutBitmap, + CFX_RenderDevice* device, + const CFX_Matrix* matrix, + int32_t barWidth, + int32_t multiple, + int32_t& e); +}; + +#endif // XFA_FXBARCODE_ONED_BC_ONEDEAN13WRITER_H_ diff --git a/xfa/fxbarcode/oned/BC_OnedEAN8Reader.cpp b/xfa/fxbarcode/oned/BC_OnedEAN8Reader.cpp new file mode 100644 index 0000000000..f3b21fde99 --- /dev/null +++ b/xfa/fxbarcode/oned/BC_OnedEAN8Reader.cpp @@ -0,0 +1,82 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com +// Original code is licensed as follows: +/* + * Copyright 2008 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "xfa/fxbarcode/BC_Reader.h" +#include "xfa/fxbarcode/common/BC_CommonBitArray.h" +#include "xfa/fxbarcode/oned/BC_OneDReader.h" +#include "xfa/fxbarcode/oned/BC_OneDimReader.h" +#include "xfa/fxbarcode/oned/BC_OnedEAN8Reader.h" +#include "xfa/fxbarcode/utils.h" + +CBC_OnedEAN8Reader::CBC_OnedEAN8Reader() {} +CBC_OnedEAN8Reader::~CBC_OnedEAN8Reader() {} +int32_t CBC_OnedEAN8Reader::DecodeMiddle(CBC_CommonBitArray* row, + CFX_Int32Array* startRange, + CFX_ByteString& resultResult, + int32_t& e) { + CFX_Int32Array counters; + counters.Add(0); + counters.Add(0); + counters.Add(0); + counters.Add(0); + int32_t end = row->GetSize(); + int32_t rowOffset = (*startRange)[1]; + int32_t rowOffsetLeft = rowOffset; + for (int32_t x = 0; x < 4 && rowOffset < end; x++) { + int32_t bestMatch = + DecodeDigit(row, &counters, rowOffset, + &(CBC_OneDimReader::L_PATTERNS[0][0]), 10, e); + BC_EXCEPTION_CHECK_ReturnValue(e, 0); + resultResult += (FX_CHAR)('0' + bestMatch); + for (int32_t i = 0; i < counters.GetSize(); i++) { + rowOffset += counters[i]; + } + } + int32_t RowOffsetLen = (rowOffset - rowOffsetLeft) / 4; + CFX_Int32Array result; + result.Add(CBC_OneDimReader::MIDDLE_PATTERN[0]); + result.Add(CBC_OneDimReader::MIDDLE_PATTERN[1]); + result.Add(CBC_OneDimReader::MIDDLE_PATTERN[2]); + result.Add(CBC_OneDimReader::MIDDLE_PATTERN[3]); + result.Add(CBC_OneDimReader::MIDDLE_PATTERN[4]); + CFX_Int32Array* middleRange = + FindGuardPattern(row, rowOffset, TRUE, &result, e); + BC_EXCEPTION_CHECK_ReturnValue(e, 0); + int32_t rowOffsetMid = rowOffset; + rowOffset = (*middleRange)[1]; + if ((rowOffset - rowOffsetMid) > RowOffsetLen) { + e = BCExceptionNotFound; + BC_EXCEPTION_CHECK_ReturnValue(e, 0); + } + delete middleRange; + for (int32_t y = 0; y < 4 && rowOffset < end; y++) { + int32_t bestMatch = + DecodeDigit(row, &counters, rowOffset, + &(CBC_OneDimReader::L_PATTERNS[0][0]), 10, e); + BC_EXCEPTION_CHECK_ReturnValue(e, 0); + resultResult += (FX_CHAR)('0' + bestMatch); + for (int32_t i = 0; i < counters.GetSize(); i++) { + rowOffset += counters[i]; + } + } + return rowOffset; +} diff --git a/xfa/fxbarcode/oned/BC_OnedEAN8Reader.h b/xfa/fxbarcode/oned/BC_OnedEAN8Reader.h new file mode 100644 index 0000000000..fe2d33d66f --- /dev/null +++ b/xfa/fxbarcode/oned/BC_OnedEAN8Reader.h @@ -0,0 +1,25 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef XFA_FXBARCODE_ONED_BC_ONEDEAN8READER_H_ +#define XFA_FXBARCODE_ONED_BC_ONEDEAN8READER_H_ + +class CBC_OneDimReader; +class CBC_CommonBitArray; +class CBC_OnedEAN8Reader; +class CBC_OnedEAN8Reader : public CBC_OneDimReader { + public: + CBC_OnedEAN8Reader(); + virtual ~CBC_OnedEAN8Reader(); + + protected: + int32_t DecodeMiddle(CBC_CommonBitArray*, + CFX_Int32Array* startRange, + CFX_ByteString& result, + int32_t& e); +}; + +#endif // XFA_FXBARCODE_ONED_BC_ONEDEAN8READER_H_ diff --git a/xfa/fxbarcode/oned/BC_OnedEAN8Writer.cpp b/xfa/fxbarcode/oned/BC_OnedEAN8Writer.cpp new file mode 100644 index 0000000000..5336867538 --- /dev/null +++ b/xfa/fxbarcode/oned/BC_OnedEAN8Writer.cpp @@ -0,0 +1,268 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com +// Original code is licensed as follows: +/* + * Copyright 2009 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "xfa/fxbarcode/BC_Reader.h" +#include "xfa/fxbarcode/BC_Writer.h" +#include "xfa/fxbarcode/common/BC_CommonBitMatrix.h" +#include "xfa/fxbarcode/oned/BC_OneDReader.h" +#include "xfa/fxbarcode/oned/BC_OneDimReader.h" +#include "xfa/fxbarcode/oned/BC_OneDimWriter.h" +#include "xfa/fxbarcode/oned/BC_OnedEAN8Writer.h" + +CBC_OnedEAN8Writer::CBC_OnedEAN8Writer() { + m_iDataLenth = 8; + m_codeWidth = 3 + (7 * 4) + 5 + (7 * 4) + 3; +} +CBC_OnedEAN8Writer::~CBC_OnedEAN8Writer() {} +void CBC_OnedEAN8Writer::SetDataLength(int32_t length) { + m_iDataLenth = 8; +} +FX_BOOL CBC_OnedEAN8Writer::SetTextLocation(BC_TEXT_LOC location) { + if (location == BC_TEXT_LOC_BELOWEMBED) { + m_locTextLoc = location; + return TRUE; + } + return FALSE; +} +FX_BOOL CBC_OnedEAN8Writer::CheckContentValidity( + const CFX_WideStringC& contents) { + for (int32_t i = 0; i < contents.GetLength(); i++) { + if (contents.GetAt(i) >= '0' && contents.GetAt(i) <= '9') { + continue; + } else { + return FALSE; + } + } + return TRUE; +} +CFX_WideString CBC_OnedEAN8Writer::FilterContents( + const CFX_WideStringC& contents) { + CFX_WideString filtercontents; + FX_WCHAR ch; + for (int32_t i = 0; i < contents.GetLength(); i++) { + ch = contents.GetAt(i); + if (ch > 175) { + i++; + continue; + } + if (ch >= '0' && ch <= '9') { + filtercontents += ch; + } + } + return filtercontents; +} +int32_t CBC_OnedEAN8Writer::CalcChecksum(const CFX_ByteString& contents) { + int32_t odd = 0; + int32_t even = 0; + int32_t j = 1; + for (int32_t i = contents.GetLength() - 1; i >= 0; i--) { + if (j % 2) { + odd += FXSYS_atoi(contents.Mid(i, 1)); + } else { + even += FXSYS_atoi(contents.Mid(i, 1)); + } + j++; + } + int32_t checksum = (odd * 3 + even) % 10; + checksum = (10 - checksum) % 10; + return (checksum); +} +uint8_t* CBC_OnedEAN8Writer::Encode(const CFX_ByteString& contents, + BCFORMAT format, + int32_t& outWidth, + int32_t& outHeight, + int32_t& e) { + uint8_t* ret = Encode(contents, format, outWidth, outHeight, 0, e); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + return ret; +} +uint8_t* CBC_OnedEAN8Writer::Encode(const CFX_ByteString& contents, + BCFORMAT format, + int32_t& outWidth, + int32_t& outHeight, + int32_t hints, + int32_t& e) { + if (format != BCFORMAT_EAN_8) { + e = BCExceptionOnlyEncodeEAN_8; + return NULL; + } + uint8_t* ret = + CBC_OneDimWriter::Encode(contents, format, outWidth, outHeight, hints, e); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + return ret; +} +uint8_t* CBC_OnedEAN8Writer::Encode(const CFX_ByteString& contents, + int32_t& outLength, + int32_t& e) { + if (contents.GetLength() != 8) { + e = BCExceptionDigitLengthMustBe8; + return NULL; + } + outLength = m_codeWidth; + uint8_t* result = FX_Alloc(uint8_t, m_codeWidth); + int32_t pos = 0; + pos += + AppendPattern(result, pos, CBC_OneDimReader::START_END_PATTERN, 3, 1, e); + if (e != BCExceptionNO) { + FX_Free(result); + return NULL; + } + int32_t i = 0; + for (i = 0; i <= 3; i++) { + int32_t digit = FXSYS_atoi(contents.Mid(i, 1)); + pos += AppendPattern(result, pos, CBC_OneDimReader::L_PATTERNS[digit], 4, 0, + e); + if (e != BCExceptionNO) { + FX_Free(result); + return NULL; + } + } + pos += AppendPattern(result, pos, CBC_OneDimReader::MIDDLE_PATTERN, 5, 0, e); + if (e != BCExceptionNO) { + FX_Free(result); + return NULL; + } + for (i = 4; i <= 7; i++) { + int32_t digit = FXSYS_atoi(contents.Mid(i, 1)); + pos += AppendPattern(result, pos, CBC_OneDimReader::L_PATTERNS[digit], 4, 1, + e); + if (e != BCExceptionNO) { + FX_Free(result); + return NULL; + } + } + pos += + AppendPattern(result, pos, CBC_OneDimReader::START_END_PATTERN, 3, 1, e); + if (e != BCExceptionNO) { + FX_Free(result); + return NULL; + } + return result; +} +void CBC_OnedEAN8Writer::ShowChars(const CFX_WideStringC& contents, + CFX_DIBitmap* pOutBitmap, + CFX_RenderDevice* device, + const CFX_Matrix* matrix, + int32_t barWidth, + int32_t multiple, + int32_t& e) { + if (device == NULL && pOutBitmap == NULL) { + e = BCExceptionIllegalArgument; + return; + } + int32_t leftPosition = 3 * multiple; + CFX_ByteString str = FX_UTF8Encode(contents); + int32_t iLength = str.GetLength(); + FXTEXT_CHARPOS* pCharPos = FX_Alloc(FXTEXT_CHARPOS, iLength); + FXSYS_memset(pCharPos, 0, sizeof(FXTEXT_CHARPOS) * iLength); + CFX_ByteString tempStr = str.Mid(0, 4); + int32_t iLen = tempStr.GetLength(); + int32_t strWidth = 7 * multiple * 4; + FX_FLOAT blank = 0.0; + CFX_FxgeDevice geBitmap; + if (pOutBitmap) { + geBitmap.Attach(pOutBitmap); + } + int32_t iFontSize = (int32_t)fabs(m_fFontSize); + int32_t iTextHeight = iFontSize + 1; + if (pOutBitmap == NULL) { + CFX_Matrix matr(m_outputHScale, 0.0, 0.0, 1.0, 0.0, 0.0); + CFX_FloatRect rect( + (FX_FLOAT)leftPosition, (FX_FLOAT)(m_Height - iTextHeight), + (FX_FLOAT)(leftPosition + strWidth - 0.5), (FX_FLOAT)m_Height); + matr.Concat(*matrix); + matr.TransformRect(rect); + FX_RECT re = rect.GetOutterRect(); + device->FillRect(&re, m_backgroundColor); + CFX_Matrix matr1(m_outputHScale, 0.0, 0.0, 1.0, 0.0, 0.0); + CFX_FloatRect rect1( + (FX_FLOAT)(leftPosition + 33 * multiple), + (FX_FLOAT)(m_Height - iTextHeight), + (FX_FLOAT)(leftPosition + 33 * multiple + strWidth - 0.5), + (FX_FLOAT)m_Height); + matr1.Concat(*matrix); + matr1.TransformRect(rect1); + re = rect1.GetOutterRect(); + device->FillRect(&re, m_backgroundColor); + } + if (pOutBitmap == NULL) { + strWidth = (int32_t)(strWidth * m_outputHScale); + } + CalcTextInfo(tempStr, pCharPos, m_pFont, (FX_FLOAT)strWidth, iFontSize, + blank); + CFX_Matrix affine_matrix(1.0, 0.0, 0.0, -1.0, 0.0, (FX_FLOAT)iFontSize); + CFX_FxgeDevice ge; + if (pOutBitmap) { + delete ge.GetBitmap(); + ge.Create(strWidth, iTextHeight, FXDIB_Argb); + ge.GetBitmap()->Clear(m_backgroundColor); + ge.DrawNormalText(iLen, pCharPos, m_pFont, + CFX_GEModule::Get()->GetFontCache(), (FX_FLOAT)iFontSize, + (CFX_Matrix*)&affine_matrix, m_fontColor, + FXTEXT_CLEARTYPE); + geBitmap.SetDIBits(ge.GetBitmap(), leftPosition, m_Height - iTextHeight); + } else { + CFX_Matrix affine_matrix1(1.0, 0.0, 0.0, -1.0, + (FX_FLOAT)leftPosition * m_outputHScale, + (FX_FLOAT)(m_Height - iTextHeight + iFontSize)); + affine_matrix1.Concat(*matrix); + device->DrawNormalText(iLen, pCharPos, m_pFont, + CFX_GEModule::Get()->GetFontCache(), + (FX_FLOAT)iFontSize, (CFX_Matrix*)&affine_matrix1, + m_fontColor, FXTEXT_CLEARTYPE); + } + tempStr = str.Mid(4, 4); + iLen = tempStr.GetLength(); + CalcTextInfo(tempStr, pCharPos + 4, m_pFont, (FX_FLOAT)strWidth, iFontSize, + blank); + if (pOutBitmap) { + delete ge.GetBitmap(); + ge.Create(strWidth, iTextHeight, FXDIB_Argb); + ge.GetBitmap()->Clear(m_backgroundColor); + ge.DrawNormalText(iLen, pCharPos + 4, m_pFont, + CFX_GEModule::Get()->GetFontCache(), (FX_FLOAT)iFontSize, + (CFX_Matrix*)&affine_matrix, m_fontColor, + FXTEXT_CLEARTYPE); + geBitmap.SetDIBits(ge.GetBitmap(), leftPosition + 33 * multiple, + m_Height - iTextHeight); + } else { + CFX_Matrix affine_matrix1( + 1.0, 0.0, 0.0, -1.0, + (FX_FLOAT)(leftPosition + 33 * multiple) * m_outputHScale, + (FX_FLOAT)(m_Height - iTextHeight + iFontSize)); + if (matrix) { + affine_matrix1.Concat(*matrix); + } + device->DrawNormalText(iLen, pCharPos + 4, m_pFont, + CFX_GEModule::Get()->GetFontCache(), + (FX_FLOAT)iFontSize, (CFX_Matrix*)&affine_matrix1, + m_fontColor, FXTEXT_CLEARTYPE); + } + FX_Free(pCharPos); +} +void CBC_OnedEAN8Writer::RenderResult(const CFX_WideStringC& contents, + uint8_t* code, + int32_t codeLength, + FX_BOOL isDevice, + int32_t& e) { + CBC_OneDimWriter::RenderResult(contents, code, codeLength, isDevice, e); +} diff --git a/xfa/fxbarcode/oned/BC_OnedEAN8Writer.h b/xfa/fxbarcode/oned/BC_OnedEAN8Writer.h new file mode 100644 index 0000000000..fc033ffcbf --- /dev/null +++ b/xfa/fxbarcode/oned/BC_OnedEAN8Writer.h @@ -0,0 +1,55 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef XFA_FXBARCODE_ONED_BC_ONEDEAN8WRITER_H_ +#define XFA_FXBARCODE_ONED_BC_ONEDEAN8WRITER_H_ + +enum BC_TEXT_LOC; +class CBC_OneDimWriter; +class CBC_OnedEAN8Writer; +class CBC_OnedEAN8Writer : public CBC_OneDimWriter { + private: + int32_t m_codeWidth; + + public: + CBC_OnedEAN8Writer(); + virtual ~CBC_OnedEAN8Writer(); + uint8_t* Encode(const CFX_ByteString& contents, + BCFORMAT format, + int32_t& outWidth, + int32_t& outHeight, + int32_t& e); + uint8_t* Encode(const CFX_ByteString& contents, + BCFORMAT format, + int32_t& outWidth, + int32_t& outHeight, + int32_t hints, + int32_t& e); + uint8_t* Encode(const CFX_ByteString& contents, + int32_t& outLength, + int32_t& e); + void RenderResult(const CFX_WideStringC& contents, + uint8_t* code, + int32_t codeLength, + FX_BOOL isDevice, + int32_t& e); + FX_BOOL CheckContentValidity(const CFX_WideStringC& contents); + CFX_WideString FilterContents(const CFX_WideStringC& contents); + void SetDataLength(int32_t length); + FX_BOOL SetTextLocation(BC_TEXT_LOC location); + int32_t CalcChecksum(const CFX_ByteString& contents); + + protected: + void ShowChars(const CFX_WideStringC& contents, + CFX_DIBitmap* pOutBitmap, + CFX_RenderDevice* device, + const CFX_Matrix* matrix, + int32_t barWidth, + int32_t multiple, + int32_t& e); +}; + +#endif // XFA_FXBARCODE_ONED_BC_ONEDEAN8WRITER_H_ diff --git a/xfa/fxbarcode/oned/BC_OnedUPCAReader.cpp b/xfa/fxbarcode/oned/BC_OnedUPCAReader.cpp new file mode 100644 index 0000000000..95b0f24775 --- /dev/null +++ b/xfa/fxbarcode/oned/BC_OnedUPCAReader.cpp @@ -0,0 +1,97 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com +// Original code is licensed as follows: +/* + * Copyright 2008 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "core/include/fxcrt/fx_basic.h" +#include "xfa/fxbarcode/BC_Reader.h" +#include "xfa/fxbarcode/oned/BC_OneDReader.h" +#include "xfa/fxbarcode/oned/BC_OneDimReader.h" +#include "xfa/fxbarcode/oned/BC_OnedEAN13Reader.h" +#include "xfa/fxbarcode/oned/BC_OnedUPCAReader.h" +#include "xfa/fxbarcode/utils.h" + +CBC_OnedUPCAReader::CBC_OnedUPCAReader() { + m_ean13Reader = NULL; +} +void CBC_OnedUPCAReader::Init() { + m_ean13Reader = new CBC_OnedEAN13Reader; +} +CBC_OnedUPCAReader::~CBC_OnedUPCAReader() { + delete m_ean13Reader; +} +CFX_ByteString CBC_OnedUPCAReader::DecodeRow(int32_t rowNumber, + CBC_CommonBitArray* row, + int32_t hints, + int32_t& e) { + CFX_ByteString bytestring = + m_ean13Reader->DecodeRow(rowNumber, row, hints, e); + BC_EXCEPTION_CHECK_ReturnValue(e, ""); + CFX_ByteString temp = MaybeReturnResult(bytestring, e); + BC_EXCEPTION_CHECK_ReturnValue(e, ""); + return temp; +} +CFX_ByteString CBC_OnedUPCAReader::DecodeRow(int32_t rowNumber, + CBC_CommonBitArray* row, + CFX_Int32Array* startGuardRange, + int32_t hints, + int32_t& e) { + CFX_ByteString bytestring = + m_ean13Reader->DecodeRow(rowNumber, row, startGuardRange, hints, e); + BC_EXCEPTION_CHECK_ReturnValue(e, ""); + CFX_ByteString temp = MaybeReturnResult(bytestring, e); + BC_EXCEPTION_CHECK_ReturnValue(e, ""); + return temp; +} +CFX_ByteString CBC_OnedUPCAReader::Decode(CBC_BinaryBitmap* image, int32_t& e) { + CFX_ByteString bytestring = m_ean13Reader->Decode(image, e); + BC_EXCEPTION_CHECK_ReturnValue(e, ""); + CFX_ByteString temp = MaybeReturnResult(bytestring, e); + BC_EXCEPTION_CHECK_ReturnValue(e, ""); + return temp; +} +CFX_ByteString CBC_OnedUPCAReader::Decode(CBC_BinaryBitmap* image, + int32_t hints, + int32_t& e) { + CFX_ByteString bytestring = m_ean13Reader->Decode(image, hints, e); + BC_EXCEPTION_CHECK_ReturnValue(e, ""); + CFX_ByteString temp = MaybeReturnResult(bytestring, e); + BC_EXCEPTION_CHECK_ReturnValue(e, ""); + return temp; +} +int32_t CBC_OnedUPCAReader::DecodeMiddle(CBC_CommonBitArray* row, + CFX_Int32Array* startRange, + CFX_ByteString& resultString, + int32_t& e) { + int32_t temp = m_ean13Reader->DecodeMiddle(row, startRange, resultString, e); + BC_EXCEPTION_CHECK_ReturnValue(e, 0); + return temp; +} +CFX_ByteString CBC_OnedUPCAReader::MaybeReturnResult(CFX_ByteString& result, + int32_t& e) { + if (result[0] == '0') { + result.Delete(0); + return result; + } else { + e = BCExceptionFormatException; + return ""; + } + return ""; +} diff --git a/xfa/fxbarcode/oned/BC_OnedUPCAReader.h b/xfa/fxbarcode/oned/BC_OnedUPCAReader.h new file mode 100644 index 0000000000..306683e1cc --- /dev/null +++ b/xfa/fxbarcode/oned/BC_OnedUPCAReader.h @@ -0,0 +1,43 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef XFA_FXBARCODE_ONED_BC_ONEDUPCAREADER_H_ +#define XFA_FXBARCODE_ONED_BC_ONEDUPCAREADER_H_ + +class CBC_BinaryBitmap; +class CBC_CommonBitArray; +class CBC_OneDimReader; +class CBC_OnedEAN13Reader; +class CBC_OnedUPCAReader; +class CBC_OnedUPCAReader : public CBC_OneDimReader { + private: + CBC_OnedEAN13Reader* m_ean13Reader; + + public: + CBC_OnedUPCAReader(); + virtual ~CBC_OnedUPCAReader(); + CFX_ByteString DecodeRow(int32_t rowNumber, + CBC_CommonBitArray* row, + int32_t hints, + int32_t& e); + CFX_ByteString DecodeRow(int32_t rowNumber, + CBC_CommonBitArray* row, + CFX_Int32Array* startGuardRange, + int32_t hints, + int32_t& e); + CFX_ByteString Decode(CBC_BinaryBitmap* image, int32_t& e); + CFX_ByteString Decode(CBC_BinaryBitmap* image, int32_t hints, int32_t& e); + virtual void Init(); + + protected: + int32_t DecodeMiddle(CBC_CommonBitArray* row, + CFX_Int32Array* startRange, + CFX_ByteString& resultString, + int32_t& e); + CFX_ByteString MaybeReturnResult(CFX_ByteString& result, int32_t& e); +}; + +#endif // XFA_FXBARCODE_ONED_BC_ONEDUPCAREADER_H_ diff --git a/xfa/fxbarcode/oned/BC_OnedUPCAWriter.cpp b/xfa/fxbarcode/oned/BC_OnedUPCAWriter.cpp new file mode 100644 index 0000000000..21ccafc20c --- /dev/null +++ b/xfa/fxbarcode/oned/BC_OnedUPCAWriter.cpp @@ -0,0 +1,286 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com +// Original code is licensed as follows: +/* + * Copyright 2010 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "xfa/fxbarcode/BC_Writer.h" +#include "xfa/fxbarcode/oned/BC_OneDimWriter.h" +#include "xfa/fxbarcode/oned/BC_OnedEAN13Writer.h" +#include "xfa/fxbarcode/oned/BC_OnedUPCAWriter.h" + +CBC_OnedUPCAWriter::CBC_OnedUPCAWriter() { + m_subWriter = NULL; + m_bLeftPadding = TRUE; + m_bRightPadding = TRUE; +} +void CBC_OnedUPCAWriter::Init() { + m_subWriter = new CBC_OnedEAN13Writer; +} +CBC_OnedUPCAWriter::~CBC_OnedUPCAWriter() { + delete m_subWriter; +} +FX_BOOL CBC_OnedUPCAWriter::CheckContentValidity( + const CFX_WideStringC& contents) { + int32_t i = 0; + for (i = 0; i < contents.GetLength(); i++) { + if (contents.GetAt(i) >= '0' && contents.GetAt(i) <= '9') { + continue; + } else { + return FALSE; + } + } + return TRUE; +} +CFX_WideString CBC_OnedUPCAWriter::FilterContents( + const CFX_WideStringC& contents) { + CFX_WideString filtercontents; + FX_WCHAR ch; + for (int32_t i = 0; i < contents.GetLength(); i++) { + ch = contents.GetAt(i); + if (ch > 175) { + i++; + continue; + } + if (ch >= '0' && ch <= '9') { + filtercontents += ch; + } + } + return filtercontents; +} +int32_t CBC_OnedUPCAWriter::CalcChecksum(const CFX_ByteString& contents) { + int32_t odd = 0; + int32_t even = 0; + int32_t j = 1; + for (int32_t i = contents.GetLength() - 1; i >= 0; i--) { + if (j % 2) { + odd += FXSYS_atoi(contents.Mid(i, 1)); + } else { + even += FXSYS_atoi(contents.Mid(i, 1)); + } + j++; + } + int32_t checksum = (odd * 3 + even) % 10; + checksum = (10 - checksum) % 10; + return (checksum); +} +uint8_t* CBC_OnedUPCAWriter::Encode(const CFX_ByteString& contents, + BCFORMAT format, + int32_t& outWidth, + int32_t& outHeight, + int32_t& e) { + uint8_t* ret = Encode(contents, format, outWidth, outHeight, 0, e); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + return ret; +} +uint8_t* CBC_OnedUPCAWriter::Encode(const CFX_ByteString& contents, + BCFORMAT format, + int32_t& outWidth, + int32_t& outHeight, + int32_t hints, + int32_t& e) { + if (format != BCFORMAT_UPC_A) { + e = BCExceptionOnlyEncodeUPC_A; + return NULL; + } + CFX_ByteString toEAN13String = '0' + contents; + m_iDataLenth = 13; + uint8_t* ret = m_subWriter->Encode(toEAN13String, BCFORMAT_EAN_13, outWidth, + outHeight, hints, e); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + return ret; +} +void CBC_OnedUPCAWriter::ShowChars(const CFX_WideStringC& contents, + CFX_DIBitmap* pOutBitmap, + CFX_RenderDevice* device, + const CFX_Matrix* matrix, + int32_t barWidth, + int32_t multiple, + int32_t& e) { + if (device == NULL && pOutBitmap == NULL) { + e = BCExceptionIllegalArgument; + return; + } + int32_t leftPadding = 7 * multiple; + int32_t leftPosition = 10 * multiple + leftPadding; + CFX_ByteString str = FX_UTF8Encode(contents); + int32_t iLen = str.GetLength(); + FXTEXT_CHARPOS* pCharPos = FX_Alloc(FXTEXT_CHARPOS, iLen); + FXSYS_memset(pCharPos, 0, sizeof(FXTEXT_CHARPOS) * iLen); + CFX_ByteString tempStr = str.Mid(1, 5); + FX_FLOAT strWidth = (FX_FLOAT)35 * multiple; + FX_FLOAT blank = 0.0; + CFX_FxgeDevice geBitmap; + if (pOutBitmap) { + geBitmap.Attach(pOutBitmap); + } + iLen = tempStr.GetLength(); + int32_t iFontSize = (int32_t)fabs(m_fFontSize); + int32_t iTextHeight = iFontSize + 1; + if (pOutBitmap == NULL) { + CFX_Matrix matr(m_outputHScale, 0.0, 0.0, 1.0, 0.0, 0.0); + CFX_FloatRect rect( + (FX_FLOAT)leftPosition, (FX_FLOAT)(m_Height - iTextHeight), + (FX_FLOAT)(leftPosition + strWidth - 0.5), (FX_FLOAT)m_Height); + matr.Concat(*matrix); + matr.TransformRect(rect); + FX_RECT re = rect.GetOutterRect(); + device->FillRect(&re, m_backgroundColor); + CFX_Matrix matr1(m_outputHScale, 0.0, 0.0, 1.0, 0.0, 0.0); + CFX_FloatRect rect1( + (FX_FLOAT)(leftPosition + 40 * multiple), + (FX_FLOAT)(m_Height - iTextHeight), + (FX_FLOAT)((leftPosition + 40 * multiple) + strWidth - 0.5), + (FX_FLOAT)m_Height); + matr1.Concat(*matrix); + matr1.TransformRect(rect1); + re = rect1.GetOutterRect(); + device->FillRect(&re, m_backgroundColor); + FX_FLOAT strWidth1 = (FX_FLOAT)multiple * 7; + CFX_Matrix matr2(m_outputHScale, 0.0, 0.0, 1.0, 0.0, 0.0); + CFX_FloatRect rect2(0.0, (FX_FLOAT)(m_Height - iTextHeight), + (FX_FLOAT)strWidth1 - 1, (FX_FLOAT)m_Height); + matr2.Concat(*matrix); + matr2.TransformRect(rect2); + re = rect2.GetOutterRect(); + device->FillRect(&re, m_backgroundColor); + CFX_Matrix matr3(m_outputHScale, 0.0, 0.0, 1.0, 0.0, 0.0); + CFX_FloatRect rect3( + (FX_FLOAT)(leftPosition + 85 * multiple), + (FX_FLOAT)(m_Height - iTextHeight), + (FX_FLOAT)((leftPosition + 85 * multiple) + strWidth1 - 0.5), + (FX_FLOAT)m_Height); + matr3.Concat(*matrix); + matr3.TransformRect(rect3); + re = rect3.GetOutterRect(); + device->FillRect(&re, m_backgroundColor); + } + if (pOutBitmap == NULL) { + strWidth = strWidth * m_outputHScale; + } + CalcTextInfo(tempStr, pCharPos + 1, m_pFont, strWidth, iFontSize, blank); + CFX_Matrix affine_matrix(1.0, 0.0, 0.0, -1.0, 0.0, (FX_FLOAT)iFontSize); + CFX_FxgeDevice ge; + if (pOutBitmap) { + ge.Create((int)strWidth, iTextHeight, FXDIB_Argb); + ge.GetBitmap()->Clear(m_backgroundColor); + ge.DrawNormalText(iLen, pCharPos + 1, m_pFont, + CFX_GEModule::Get()->GetFontCache(), (FX_FLOAT)iFontSize, + (CFX_Matrix*)&affine_matrix, m_fontColor, + FXTEXT_CLEARTYPE); + geBitmap.SetDIBits(ge.GetBitmap(), leftPosition, m_Height - iTextHeight); + } else { + CFX_Matrix affine_matrix1(1.0, 0.0, 0.0, -1.0, + (FX_FLOAT)leftPosition * m_outputHScale, + (FX_FLOAT)(m_Height - iTextHeight + iFontSize)); + if (matrix) { + affine_matrix1.Concat(*matrix); + } + device->DrawNormalText(iLen, pCharPos + 1, m_pFont, + CFX_GEModule::Get()->GetFontCache(), + (FX_FLOAT)iFontSize, (CFX_Matrix*)&affine_matrix1, + m_fontColor, FXTEXT_CLEARTYPE); + } + tempStr = str.Mid(6, 5); + iLen = tempStr.GetLength(); + CalcTextInfo(tempStr, pCharPos + 6, m_pFont, strWidth, iFontSize, blank); + if (pOutBitmap) { + FX_RECT rect2(0, 0, (int)strWidth, iTextHeight); + ge.FillRect(&rect2, m_backgroundColor); + ge.DrawNormalText(iLen, pCharPos + 6, m_pFont, + CFX_GEModule::Get()->GetFontCache(), (FX_FLOAT)iFontSize, + (CFX_Matrix*)&affine_matrix, m_fontColor, + FXTEXT_CLEARTYPE); + geBitmap.SetDIBits(ge.GetBitmap(), leftPosition + 40 * multiple, + m_Height - iTextHeight); + } else { + CFX_Matrix affine_matrix1( + 1.0, 0.0, 0.0, -1.0, + (FX_FLOAT)(leftPosition + 40 * multiple) * m_outputHScale, + (FX_FLOAT)(m_Height - iTextHeight + iFontSize)); + if (matrix) { + affine_matrix1.Concat(*matrix); + } + device->DrawNormalText(iLen, pCharPos + 6, m_pFont, + CFX_GEModule::Get()->GetFontCache(), + (FX_FLOAT)iFontSize, (CFX_Matrix*)&affine_matrix1, + m_fontColor, FXTEXT_CLEARTYPE); + } + tempStr = str.Mid(0, 1); + iLen = tempStr.GetLength(); + strWidth = (FX_FLOAT)multiple * 7; + if (pOutBitmap == NULL) { + strWidth = strWidth * m_outputHScale; + } + CalcTextInfo(tempStr, pCharPos, m_pFont, strWidth, iFontSize, blank); + if (pOutBitmap) { + delete ge.GetBitmap(); + ge.Create((int)strWidth, iTextHeight, FXDIB_Argb); + ge.GetBitmap()->Clear(m_backgroundColor); + ge.DrawNormalText(iLen, pCharPos, m_pFont, + CFX_GEModule::Get()->GetFontCache(), (FX_FLOAT)iFontSize, + (CFX_Matrix*)&affine_matrix, m_fontColor, + FXTEXT_CLEARTYPE); + geBitmap.SetDIBits(ge.GetBitmap(), 0, m_Height - iTextHeight); + } else { + CFX_Matrix affine_matrix1(1.0, 0.0, 0.0, -1.0, 0, + (FX_FLOAT)(m_Height - iTextHeight + iFontSize)); + if (matrix) { + affine_matrix1.Concat(*matrix); + } + device->DrawNormalText(iLen, pCharPos, m_pFont, + CFX_GEModule::Get()->GetFontCache(), + (FX_FLOAT)iFontSize, (CFX_Matrix*)&affine_matrix1, + m_fontColor, FXTEXT_CLEARTYPE); + } + tempStr = str.Mid(11, 1); + iLen = tempStr.GetLength(); + CalcTextInfo(tempStr, pCharPos + 11, m_pFont, strWidth, iFontSize, blank); + if (pOutBitmap) { + delete ge.GetBitmap(); + ge.Create((int)strWidth, iTextHeight, FXDIB_Argb); + ge.GetBitmap()->Clear(m_backgroundColor); + ge.DrawNormalText(iLen, pCharPos + 11, m_pFont, + CFX_GEModule::Get()->GetFontCache(), (FX_FLOAT)iFontSize, + (CFX_Matrix*)&affine_matrix, m_fontColor, + FXTEXT_CLEARTYPE); + geBitmap.SetDIBits(ge.GetBitmap(), leftPosition + 85 * multiple, + m_Height - iTextHeight); + } else { + CFX_Matrix affine_matrix1( + 1.0, 0.0, 0.0, -1.0, + (FX_FLOAT)(leftPosition + 85 * multiple) * m_outputHScale, + (FX_FLOAT)(m_Height - iTextHeight + iFontSize)); + if (matrix) { + affine_matrix1.Concat(*matrix); + } + device->DrawNormalText(iLen, pCharPos + 11, m_pFont, + CFX_GEModule::Get()->GetFontCache(), + (FX_FLOAT)iFontSize, (CFX_Matrix*)&affine_matrix1, + m_fontColor, FXTEXT_CLEARTYPE); + } + FX_Free(pCharPos); +} +void CBC_OnedUPCAWriter::RenderResult(const CFX_WideStringC& contents, + uint8_t* code, + int32_t codeLength, + FX_BOOL isDevice, + int32_t& e) { + CBC_OneDimWriter::RenderResult(contents, code, codeLength, isDevice, e); +} diff --git a/xfa/fxbarcode/oned/BC_OnedUPCAWriter.h b/xfa/fxbarcode/oned/BC_OnedUPCAWriter.h new file mode 100644 index 0000000000..f376929b1b --- /dev/null +++ b/xfa/fxbarcode/oned/BC_OnedUPCAWriter.h @@ -0,0 +1,55 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef XFA_FXBARCODE_ONED_BC_ONEDUPCAWRITER_H_ +#define XFA_FXBARCODE_ONED_BC_ONEDUPCAWRITER_H_ + +class CBC_OnedEAN13Writer; +class CBC_OnedUPCAWriter; +class CBC_OnedUPCAWriter : public CBC_OneDimWriter { + private: + CBC_OnedEAN13Writer* m_subWriter; + + public: + CBC_OnedUPCAWriter(); + virtual ~CBC_OnedUPCAWriter(); + virtual void Init(); + uint8_t* Encode(const CFX_ByteString& contents, + BCFORMAT format, + int32_t& outWidth, + int32_t& outHeight, + int32_t& e); + uint8_t* Encode(const CFX_ByteString& contents, + BCFORMAT format, + int32_t& outWidth, + int32_t& outHeight, + int32_t hints, + int32_t& e); + uint8_t* Encode(const CFX_ByteString& contents, + int32_t& outLength, + int32_t& e) { + return nullptr; + } + void RenderResult(const CFX_WideStringC& contents, + uint8_t* code, + int32_t codeLength, + FX_BOOL isDevice, + int32_t& e); + FX_BOOL CheckContentValidity(const CFX_WideStringC& contents); + CFX_WideString FilterContents(const CFX_WideStringC& contents); + int32_t CalcChecksum(const CFX_ByteString& contents); + + protected: + void ShowChars(const CFX_WideStringC& contents, + CFX_DIBitmap* pOutBitmap, + CFX_RenderDevice* device, + const CFX_Matrix* matrix, + int32_t barWidth, + int32_t multiple, + int32_t& e); +}; + +#endif // XFA_FXBARCODE_ONED_BC_ONEDUPCAWRITER_H_ diff --git a/xfa/fxbarcode/pdf417/BC_PDF417.cpp b/xfa/fxbarcode/pdf417/BC_PDF417.cpp new file mode 100644 index 0000000000..e57a79e17e --- /dev/null +++ b/xfa/fxbarcode/pdf417/BC_PDF417.cpp @@ -0,0 +1,586 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com +// Original code is licensed as follows: +/* + * Copyright 2006 Jeremias Maerki in part, and ZXing Authors in part + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "xfa/fxbarcode/pdf417/BC_PDF417.h" +#include "xfa/fxbarcode/pdf417/BC_PDF417BarcodeMatrix.h" +#include "xfa/fxbarcode/pdf417/BC_PDF417BarcodeRow.h" +#include "xfa/fxbarcode/pdf417/BC_PDF417Compaction.h" +#include "xfa/fxbarcode/pdf417/BC_PDF417ErrorCorrection.h" +#include "xfa/fxbarcode/pdf417/BC_PDF417HighLevelEncoder.h" +#include "xfa/fxbarcode/utils.h" + +int32_t CBC_PDF417::START_PATTERN = 0x1fea8; +int32_t CBC_PDF417::STOP_PATTERN = 0x3fa29; +int32_t CBC_PDF417::CODEWORD_TABLE[][1000] = { + {0x1d5c0, 0x1eaf0, 0x1f57c, 0x1d4e0, 0x1ea78, 0x1f53e, 0x1a8c0, 0x1d470, + 0x1a860, 0x15040, 0x1a830, 0x15020, 0x1adc0, 0x1d6f0, 0x1eb7c, 0x1ace0, + 0x1d678, 0x1eb3e, 0x158c0, 0x1ac70, 0x15860, 0x15dc0, 0x1aef0, 0x1d77c, + 0x15ce0, 0x1ae78, 0x1d73e, 0x15c70, 0x1ae3c, 0x15ef0, 0x1af7c, 0x15e78, + 0x1af3e, 0x15f7c, 0x1f5fa, 0x1d2e0, 0x1e978, 0x1f4be, 0x1a4c0, 0x1d270, + 0x1e93c, 0x1a460, 0x1d238, 0x14840, 0x1a430, 0x1d21c, 0x14820, 0x1a418, + 0x14810, 0x1a6e0, 0x1d378, 0x1e9be, 0x14cc0, 0x1a670, 0x1d33c, 0x14c60, + 0x1a638, 0x1d31e, 0x14c30, 0x1a61c, 0x14ee0, 0x1a778, 0x1d3be, 0x14e70, + 0x1a73c, 0x14e38, 0x1a71e, 0x14f78, 0x1a7be, 0x14f3c, 0x14f1e, 0x1a2c0, + 0x1d170, 0x1e8bc, 0x1a260, 0x1d138, 0x1e89e, 0x14440, 0x1a230, 0x1d11c, + 0x14420, 0x1a218, 0x14410, 0x14408, 0x146c0, 0x1a370, 0x1d1bc, 0x14660, + 0x1a338, 0x1d19e, 0x14630, 0x1a31c, 0x14618, 0x1460c, 0x14770, 0x1a3bc, + 0x14738, 0x1a39e, 0x1471c, 0x147bc, 0x1a160, 0x1d0b8, 0x1e85e, 0x14240, + 0x1a130, 0x1d09c, 0x14220, 0x1a118, 0x1d08e, 0x14210, 0x1a10c, 0x14208, + 0x1a106, 0x14360, 0x1a1b8, 0x1d0de, 0x14330, 0x1a19c, 0x14318, 0x1a18e, + 0x1430c, 0x14306, 0x1a1de, 0x1438e, 0x14140, 0x1a0b0, 0x1d05c, 0x14120, + 0x1a098, 0x1d04e, 0x14110, 0x1a08c, 0x14108, 0x1a086, 0x14104, 0x141b0, + 0x14198, 0x1418c, 0x140a0, 0x1d02e, 0x1a04c, 0x1a046, 0x14082, 0x1cae0, + 0x1e578, 0x1f2be, 0x194c0, 0x1ca70, 0x1e53c, 0x19460, 0x1ca38, 0x1e51e, + 0x12840, 0x19430, 0x12820, 0x196e0, 0x1cb78, 0x1e5be, 0x12cc0, 0x19670, + 0x1cb3c, 0x12c60, 0x19638, 0x12c30, 0x12c18, 0x12ee0, 0x19778, 0x1cbbe, + 0x12e70, 0x1973c, 0x12e38, 0x12e1c, 0x12f78, 0x197be, 0x12f3c, 0x12fbe, + 0x1dac0, 0x1ed70, 0x1f6bc, 0x1da60, 0x1ed38, 0x1f69e, 0x1b440, 0x1da30, + 0x1ed1c, 0x1b420, 0x1da18, 0x1ed0e, 0x1b410, 0x1da0c, 0x192c0, 0x1c970, + 0x1e4bc, 0x1b6c0, 0x19260, 0x1c938, 0x1e49e, 0x1b660, 0x1db38, 0x1ed9e, + 0x16c40, 0x12420, 0x19218, 0x1c90e, 0x16c20, 0x1b618, 0x16c10, 0x126c0, + 0x19370, 0x1c9bc, 0x16ec0, 0x12660, 0x19338, 0x1c99e, 0x16e60, 0x1b738, + 0x1db9e, 0x16e30, 0x12618, 0x16e18, 0x12770, 0x193bc, 0x16f70, 0x12738, + 0x1939e, 0x16f38, 0x1b79e, 0x16f1c, 0x127bc, 0x16fbc, 0x1279e, 0x16f9e, + 0x1d960, 0x1ecb8, 0x1f65e, 0x1b240, 0x1d930, 0x1ec9c, 0x1b220, 0x1d918, + 0x1ec8e, 0x1b210, 0x1d90c, 0x1b208, 0x1b204, 0x19160, 0x1c8b8, 0x1e45e, + 0x1b360, 0x19130, 0x1c89c, 0x16640, 0x12220, 0x1d99c, 0x1c88e, 0x16620, + 0x12210, 0x1910c, 0x16610, 0x1b30c, 0x19106, 0x12204, 0x12360, 0x191b8, + 0x1c8de, 0x16760, 0x12330, 0x1919c, 0x16730, 0x1b39c, 0x1918e, 0x16718, + 0x1230c, 0x12306, 0x123b8, 0x191de, 0x167b8, 0x1239c, 0x1679c, 0x1238e, + 0x1678e, 0x167de, 0x1b140, 0x1d8b0, 0x1ec5c, 0x1b120, 0x1d898, 0x1ec4e, + 0x1b110, 0x1d88c, 0x1b108, 0x1d886, 0x1b104, 0x1b102, 0x12140, 0x190b0, + 0x1c85c, 0x16340, 0x12120, 0x19098, 0x1c84e, 0x16320, 0x1b198, 0x1d8ce, + 0x16310, 0x12108, 0x19086, 0x16308, 0x1b186, 0x16304, 0x121b0, 0x190dc, + 0x163b0, 0x12198, 0x190ce, 0x16398, 0x1b1ce, 0x1638c, 0x12186, 0x16386, + 0x163dc, 0x163ce, 0x1b0a0, 0x1d858, 0x1ec2e, 0x1b090, 0x1d84c, 0x1b088, + 0x1d846, 0x1b084, 0x1b082, 0x120a0, 0x19058, 0x1c82e, 0x161a0, 0x12090, + 0x1904c, 0x16190, 0x1b0cc, 0x19046, 0x16188, 0x12084, 0x16184, 0x12082, + 0x120d8, 0x161d8, 0x161cc, 0x161c6, 0x1d82c, 0x1d826, 0x1b042, 0x1902c, + 0x12048, 0x160c8, 0x160c4, 0x160c2, 0x18ac0, 0x1c570, 0x1e2bc, 0x18a60, + 0x1c538, 0x11440, 0x18a30, 0x1c51c, 0x11420, 0x18a18, 0x11410, 0x11408, + 0x116c0, 0x18b70, 0x1c5bc, 0x11660, 0x18b38, 0x1c59e, 0x11630, 0x18b1c, + 0x11618, 0x1160c, 0x11770, 0x18bbc, 0x11738, 0x18b9e, 0x1171c, 0x117bc, + 0x1179e, 0x1cd60, 0x1e6b8, 0x1f35e, 0x19a40, 0x1cd30, 0x1e69c, 0x19a20, + 0x1cd18, 0x1e68e, 0x19a10, 0x1cd0c, 0x19a08, 0x1cd06, 0x18960, 0x1c4b8, + 0x1e25e, 0x19b60, 0x18930, 0x1c49c, 0x13640, 0x11220, 0x1cd9c, 0x1c48e, + 0x13620, 0x19b18, 0x1890c, 0x13610, 0x11208, 0x13608, 0x11360, 0x189b8, + 0x1c4de, 0x13760, 0x11330, 0x1cdde, 0x13730, 0x19b9c, 0x1898e, 0x13718, + 0x1130c, 0x1370c, 0x113b8, 0x189de, 0x137b8, 0x1139c, 0x1379c, 0x1138e, + 0x113de, 0x137de, 0x1dd40, 0x1eeb0, 0x1f75c, 0x1dd20, 0x1ee98, 0x1f74e, + 0x1dd10, 0x1ee8c, 0x1dd08, 0x1ee86, 0x1dd04, 0x19940, 0x1ccb0, 0x1e65c, + 0x1bb40, 0x19920, 0x1eedc, 0x1e64e, 0x1bb20, 0x1dd98, 0x1eece, 0x1bb10, + 0x19908, 0x1cc86, 0x1bb08, 0x1dd86, 0x19902, 0x11140, 0x188b0, 0x1c45c, + 0x13340, 0x11120, 0x18898, 0x1c44e, 0x17740, 0x13320, 0x19998, 0x1ccce, + 0x17720, 0x1bb98, 0x1ddce, 0x18886, 0x17710, 0x13308, 0x19986, 0x17708, + 0x11102, 0x111b0, 0x188dc, 0x133b0, 0x11198, 0x188ce, 0x177b0, 0x13398, + 0x199ce, 0x17798, 0x1bbce, 0x11186, 0x13386, 0x111dc, 0x133dc, 0x111ce, + 0x177dc, 0x133ce, 0x1dca0, 0x1ee58, 0x1f72e, 0x1dc90, 0x1ee4c, 0x1dc88, + 0x1ee46, 0x1dc84, 0x1dc82, 0x198a0, 0x1cc58, 0x1e62e, 0x1b9a0, 0x19890, + 0x1ee6e, 0x1b990, 0x1dccc, 0x1cc46, 0x1b988, 0x19884, 0x1b984, 0x19882, + 0x1b982, 0x110a0, 0x18858, 0x1c42e, 0x131a0, 0x11090, 0x1884c, 0x173a0, + 0x13190, 0x198cc, 0x18846, 0x17390, 0x1b9cc, 0x11084, 0x17388, 0x13184, + 0x11082, 0x13182, 0x110d8, 0x1886e, 0x131d8, 0x110cc, 0x173d8, 0x131cc, + 0x110c6, 0x173cc, 0x131c6, 0x110ee, 0x173ee, 0x1dc50, 0x1ee2c, 0x1dc48, + 0x1ee26, 0x1dc44, 0x1dc42, 0x19850, 0x1cc2c, 0x1b8d0, 0x19848, 0x1cc26, + 0x1b8c8, 0x1dc66, 0x1b8c4, 0x19842, 0x1b8c2, 0x11050, 0x1882c, 0x130d0, + 0x11048, 0x18826, 0x171d0, 0x130c8, 0x19866, 0x171c8, 0x1b8e6, 0x11042, + 0x171c4, 0x130c2, 0x171c2, 0x130ec, 0x171ec, 0x171e6, 0x1ee16, 0x1dc22, + 0x1cc16, 0x19824, 0x19822, 0x11028, 0x13068, 0x170e8, 0x11022, 0x13062, + 0x18560, 0x10a40, 0x18530, 0x10a20, 0x18518, 0x1c28e, 0x10a10, 0x1850c, + 0x10a08, 0x18506, 0x10b60, 0x185b8, 0x1c2de, 0x10b30, 0x1859c, 0x10b18, + 0x1858e, 0x10b0c, 0x10b06, 0x10bb8, 0x185de, 0x10b9c, 0x10b8e, 0x10bde, + 0x18d40, 0x1c6b0, 0x1e35c, 0x18d20, 0x1c698, 0x18d10, 0x1c68c, 0x18d08, + 0x1c686, 0x18d04, 0x10940, 0x184b0, 0x1c25c, 0x11b40, 0x10920, 0x1c6dc, + 0x1c24e, 0x11b20, 0x18d98, 0x1c6ce, 0x11b10, 0x10908, 0x18486, 0x11b08, + 0x18d86, 0x10902, 0x109b0, 0x184dc, 0x11bb0, 0x10998, 0x184ce, 0x11b98, + 0x18dce, 0x11b8c, 0x10986, 0x109dc, 0x11bdc, 0x109ce, 0x11bce, 0x1cea0, + 0x1e758, 0x1f3ae, 0x1ce90, 0x1e74c, 0x1ce88, 0x1e746, 0x1ce84, 0x1ce82, + 0x18ca0, 0x1c658, 0x19da0, 0x18c90, 0x1c64c, 0x19d90, 0x1cecc, 0x1c646, + 0x19d88, 0x18c84, 0x19d84, 0x18c82, 0x19d82, 0x108a0, 0x18458, 0x119a0, + 0x10890, 0x1c66e, 0x13ba0, 0x11990, 0x18ccc, 0x18446, 0x13b90, 0x19dcc, + 0x10884, 0x13b88, 0x11984, 0x10882, 0x11982, 0x108d8, 0x1846e, 0x119d8, + 0x108cc, 0x13bd8, 0x119cc, 0x108c6, 0x13bcc, 0x119c6, 0x108ee, 0x119ee, + 0x13bee, 0x1ef50, 0x1f7ac, 0x1ef48, 0x1f7a6, 0x1ef44, 0x1ef42, 0x1ce50, + 0x1e72c, 0x1ded0, 0x1ef6c, 0x1e726, 0x1dec8, 0x1ef66, 0x1dec4, 0x1ce42, + 0x1dec2, 0x18c50, 0x1c62c, 0x19cd0, 0x18c48, 0x1c626, 0x1bdd0, 0x19cc8, + 0x1ce66, 0x1bdc8, 0x1dee6, 0x18c42, 0x1bdc4, 0x19cc2, 0x1bdc2, 0x10850, + 0x1842c, 0x118d0, 0x10848, 0x18426, 0x139d0, 0x118c8, 0x18c66, 0x17bd0, + 0x139c8, 0x19ce6, 0x10842, 0x17bc8, 0x1bde6, 0x118c2, 0x17bc4, 0x1086c, + 0x118ec, 0x10866, 0x139ec, 0x118e6, 0x17bec, 0x139e6, 0x17be6, 0x1ef28, + 0x1f796, 0x1ef24, 0x1ef22, 0x1ce28, 0x1e716, 0x1de68, 0x1ef36, 0x1de64, + 0x1ce22, 0x1de62, 0x18c28, 0x1c616, 0x19c68, 0x18c24, 0x1bce8, 0x19c64, + 0x18c22, 0x1bce4, 0x19c62, 0x1bce2, 0x10828, 0x18416, 0x11868, 0x18c36, + 0x138e8, 0x11864, 0x10822, 0x179e8, 0x138e4, 0x11862, 0x179e4, 0x138e2, + 0x179e2, 0x11876, 0x179f6, 0x1ef12, 0x1de34, 0x1de32, 0x19c34, 0x1bc74, + 0x1bc72, 0x11834, 0x13874, 0x178f4, 0x178f2, 0x10540, 0x10520, 0x18298, + 0x10510, 0x10508, 0x10504, 0x105b0, 0x10598, 0x1058c, 0x10586, 0x105dc, + 0x105ce, 0x186a0, 0x18690, 0x1c34c, 0x18688, 0x1c346, 0x18684, 0x18682, + 0x104a0, 0x18258, 0x10da0, 0x186d8, 0x1824c, 0x10d90, 0x186cc, 0x10d88, + 0x186c6, 0x10d84, 0x10482, 0x10d82, 0x104d8, 0x1826e, 0x10dd8, 0x186ee, + 0x10dcc, 0x104c6, 0x10dc6, 0x104ee, 0x10dee, 0x1c750, 0x1c748, 0x1c744, + 0x1c742, 0x18650, 0x18ed0, 0x1c76c, 0x1c326, 0x18ec8, 0x1c766, 0x18ec4, + 0x18642, 0x18ec2, 0x10450, 0x10cd0, 0x10448, 0x18226, 0x11dd0, 0x10cc8, + 0x10444, 0x11dc8, 0x10cc4, 0x10442, 0x11dc4, 0x10cc2, 0x1046c, 0x10cec, + 0x10466, 0x11dec, 0x10ce6, 0x11de6, 0x1e7a8, 0x1e7a4, 0x1e7a2, 0x1c728, + 0x1cf68, 0x1e7b6, 0x1cf64, 0x1c722, 0x1cf62, 0x18628, 0x1c316, 0x18e68, + 0x1c736, 0x19ee8, 0x18e64, 0x18622, 0x19ee4, 0x18e62, 0x19ee2, 0x10428, + 0x18216, 0x10c68, 0x18636, 0x11ce8, 0x10c64, 0x10422, 0x13de8, 0x11ce4, + 0x10c62, 0x13de4, 0x11ce2, 0x10436, 0x10c76, 0x11cf6, 0x13df6, 0x1f7d4, + 0x1f7d2, 0x1e794, 0x1efb4, 0x1e792, 0x1efb2, 0x1c714, 0x1cf34, 0x1c712, + 0x1df74, 0x1cf32, 0x1df72, 0x18614, 0x18e34, 0x18612, 0x19e74, 0x18e32, + 0x1bef4}, + {0x1f560, 0x1fab8, 0x1ea40, 0x1f530, 0x1fa9c, 0x1ea20, 0x1f518, 0x1fa8e, + 0x1ea10, 0x1f50c, 0x1ea08, 0x1f506, 0x1ea04, 0x1eb60, 0x1f5b8, 0x1fade, + 0x1d640, 0x1eb30, 0x1f59c, 0x1d620, 0x1eb18, 0x1f58e, 0x1d610, 0x1eb0c, + 0x1d608, 0x1eb06, 0x1d604, 0x1d760, 0x1ebb8, 0x1f5de, 0x1ae40, 0x1d730, + 0x1eb9c, 0x1ae20, 0x1d718, 0x1eb8e, 0x1ae10, 0x1d70c, 0x1ae08, 0x1d706, + 0x1ae04, 0x1af60, 0x1d7b8, 0x1ebde, 0x15e40, 0x1af30, 0x1d79c, 0x15e20, + 0x1af18, 0x1d78e, 0x15e10, 0x1af0c, 0x15e08, 0x1af06, 0x15f60, 0x1afb8, + 0x1d7de, 0x15f30, 0x1af9c, 0x15f18, 0x1af8e, 0x15f0c, 0x15fb8, 0x1afde, + 0x15f9c, 0x15f8e, 0x1e940, 0x1f4b0, 0x1fa5c, 0x1e920, 0x1f498, 0x1fa4e, + 0x1e910, 0x1f48c, 0x1e908, 0x1f486, 0x1e904, 0x1e902, 0x1d340, 0x1e9b0, + 0x1f4dc, 0x1d320, 0x1e998, 0x1f4ce, 0x1d310, 0x1e98c, 0x1d308, 0x1e986, + 0x1d304, 0x1d302, 0x1a740, 0x1d3b0, 0x1e9dc, 0x1a720, 0x1d398, 0x1e9ce, + 0x1a710, 0x1d38c, 0x1a708, 0x1d386, 0x1a704, 0x1a702, 0x14f40, 0x1a7b0, + 0x1d3dc, 0x14f20, 0x1a798, 0x1d3ce, 0x14f10, 0x1a78c, 0x14f08, 0x1a786, + 0x14f04, 0x14fb0, 0x1a7dc, 0x14f98, 0x1a7ce, 0x14f8c, 0x14f86, 0x14fdc, + 0x14fce, 0x1e8a0, 0x1f458, 0x1fa2e, 0x1e890, 0x1f44c, 0x1e888, 0x1f446, + 0x1e884, 0x1e882, 0x1d1a0, 0x1e8d8, 0x1f46e, 0x1d190, 0x1e8cc, 0x1d188, + 0x1e8c6, 0x1d184, 0x1d182, 0x1a3a0, 0x1d1d8, 0x1e8ee, 0x1a390, 0x1d1cc, + 0x1a388, 0x1d1c6, 0x1a384, 0x1a382, 0x147a0, 0x1a3d8, 0x1d1ee, 0x14790, + 0x1a3cc, 0x14788, 0x1a3c6, 0x14784, 0x14782, 0x147d8, 0x1a3ee, 0x147cc, + 0x147c6, 0x147ee, 0x1e850, 0x1f42c, 0x1e848, 0x1f426, 0x1e844, 0x1e842, + 0x1d0d0, 0x1e86c, 0x1d0c8, 0x1e866, 0x1d0c4, 0x1d0c2, 0x1a1d0, 0x1d0ec, + 0x1a1c8, 0x1d0e6, 0x1a1c4, 0x1a1c2, 0x143d0, 0x1a1ec, 0x143c8, 0x1a1e6, + 0x143c4, 0x143c2, 0x143ec, 0x143e6, 0x1e828, 0x1f416, 0x1e824, 0x1e822, + 0x1d068, 0x1e836, 0x1d064, 0x1d062, 0x1a0e8, 0x1d076, 0x1a0e4, 0x1a0e2, + 0x141e8, 0x1a0f6, 0x141e4, 0x141e2, 0x1e814, 0x1e812, 0x1d034, 0x1d032, + 0x1a074, 0x1a072, 0x1e540, 0x1f2b0, 0x1f95c, 0x1e520, 0x1f298, 0x1f94e, + 0x1e510, 0x1f28c, 0x1e508, 0x1f286, 0x1e504, 0x1e502, 0x1cb40, 0x1e5b0, + 0x1f2dc, 0x1cb20, 0x1e598, 0x1f2ce, 0x1cb10, 0x1e58c, 0x1cb08, 0x1e586, + 0x1cb04, 0x1cb02, 0x19740, 0x1cbb0, 0x1e5dc, 0x19720, 0x1cb98, 0x1e5ce, + 0x19710, 0x1cb8c, 0x19708, 0x1cb86, 0x19704, 0x19702, 0x12f40, 0x197b0, + 0x1cbdc, 0x12f20, 0x19798, 0x1cbce, 0x12f10, 0x1978c, 0x12f08, 0x19786, + 0x12f04, 0x12fb0, 0x197dc, 0x12f98, 0x197ce, 0x12f8c, 0x12f86, 0x12fdc, + 0x12fce, 0x1f6a0, 0x1fb58, 0x16bf0, 0x1f690, 0x1fb4c, 0x169f8, 0x1f688, + 0x1fb46, 0x168fc, 0x1f684, 0x1f682, 0x1e4a0, 0x1f258, 0x1f92e, 0x1eda0, + 0x1e490, 0x1fb6e, 0x1ed90, 0x1f6cc, 0x1f246, 0x1ed88, 0x1e484, 0x1ed84, + 0x1e482, 0x1ed82, 0x1c9a0, 0x1e4d8, 0x1f26e, 0x1dba0, 0x1c990, 0x1e4cc, + 0x1db90, 0x1edcc, 0x1e4c6, 0x1db88, 0x1c984, 0x1db84, 0x1c982, 0x1db82, + 0x193a0, 0x1c9d8, 0x1e4ee, 0x1b7a0, 0x19390, 0x1c9cc, 0x1b790, 0x1dbcc, + 0x1c9c6, 0x1b788, 0x19384, 0x1b784, 0x19382, 0x1b782, 0x127a0, 0x193d8, + 0x1c9ee, 0x16fa0, 0x12790, 0x193cc, 0x16f90, 0x1b7cc, 0x193c6, 0x16f88, + 0x12784, 0x16f84, 0x12782, 0x127d8, 0x193ee, 0x16fd8, 0x127cc, 0x16fcc, + 0x127c6, 0x16fc6, 0x127ee, 0x1f650, 0x1fb2c, 0x165f8, 0x1f648, 0x1fb26, + 0x164fc, 0x1f644, 0x1647e, 0x1f642, 0x1e450, 0x1f22c, 0x1ecd0, 0x1e448, + 0x1f226, 0x1ecc8, 0x1f666, 0x1ecc4, 0x1e442, 0x1ecc2, 0x1c8d0, 0x1e46c, + 0x1d9d0, 0x1c8c8, 0x1e466, 0x1d9c8, 0x1ece6, 0x1d9c4, 0x1c8c2, 0x1d9c2, + 0x191d0, 0x1c8ec, 0x1b3d0, 0x191c8, 0x1c8e6, 0x1b3c8, 0x1d9e6, 0x1b3c4, + 0x191c2, 0x1b3c2, 0x123d0, 0x191ec, 0x167d0, 0x123c8, 0x191e6, 0x167c8, + 0x1b3e6, 0x167c4, 0x123c2, 0x167c2, 0x123ec, 0x167ec, 0x123e6, 0x167e6, + 0x1f628, 0x1fb16, 0x162fc, 0x1f624, 0x1627e, 0x1f622, 0x1e428, 0x1f216, + 0x1ec68, 0x1f636, 0x1ec64, 0x1e422, 0x1ec62, 0x1c868, 0x1e436, 0x1d8e8, + 0x1c864, 0x1d8e4, 0x1c862, 0x1d8e2, 0x190e8, 0x1c876, 0x1b1e8, 0x1d8f6, + 0x1b1e4, 0x190e2, 0x1b1e2, 0x121e8, 0x190f6, 0x163e8, 0x121e4, 0x163e4, + 0x121e2, 0x163e2, 0x121f6, 0x163f6, 0x1f614, 0x1617e, 0x1f612, 0x1e414, + 0x1ec34, 0x1e412, 0x1ec32, 0x1c834, 0x1d874, 0x1c832, 0x1d872, 0x19074, + 0x1b0f4, 0x19072, 0x1b0f2, 0x120f4, 0x161f4, 0x120f2, 0x161f2, 0x1f60a, + 0x1e40a, 0x1ec1a, 0x1c81a, 0x1d83a, 0x1903a, 0x1b07a, 0x1e2a0, 0x1f158, + 0x1f8ae, 0x1e290, 0x1f14c, 0x1e288, 0x1f146, 0x1e284, 0x1e282, 0x1c5a0, + 0x1e2d8, 0x1f16e, 0x1c590, 0x1e2cc, 0x1c588, 0x1e2c6, 0x1c584, 0x1c582, + 0x18ba0, 0x1c5d8, 0x1e2ee, 0x18b90, 0x1c5cc, 0x18b88, 0x1c5c6, 0x18b84, + 0x18b82, 0x117a0, 0x18bd8, 0x1c5ee, 0x11790, 0x18bcc, 0x11788, 0x18bc6, + 0x11784, 0x11782, 0x117d8, 0x18bee, 0x117cc, 0x117c6, 0x117ee, 0x1f350, + 0x1f9ac, 0x135f8, 0x1f348, 0x1f9a6, 0x134fc, 0x1f344, 0x1347e, 0x1f342, + 0x1e250, 0x1f12c, 0x1e6d0, 0x1e248, 0x1f126, 0x1e6c8, 0x1f366, 0x1e6c4, + 0x1e242, 0x1e6c2, 0x1c4d0, 0x1e26c, 0x1cdd0, 0x1c4c8, 0x1e266, 0x1cdc8, + 0x1e6e6, 0x1cdc4, 0x1c4c2, 0x1cdc2, 0x189d0, 0x1c4ec, 0x19bd0, 0x189c8, + 0x1c4e6, 0x19bc8, 0x1cde6, 0x19bc4, 0x189c2, 0x19bc2, 0x113d0, 0x189ec, + 0x137d0, 0x113c8, 0x189e6, 0x137c8, 0x19be6, 0x137c4, 0x113c2, 0x137c2, + 0x113ec, 0x137ec, 0x113e6, 0x137e6, 0x1fba8, 0x175f0, 0x1bafc, 0x1fba4, + 0x174f8, 0x1ba7e, 0x1fba2, 0x1747c, 0x1743e, 0x1f328, 0x1f996, 0x132fc, + 0x1f768, 0x1fbb6, 0x176fc, 0x1327e, 0x1f764, 0x1f322, 0x1767e, 0x1f762, + 0x1e228, 0x1f116, 0x1e668, 0x1e224, 0x1eee8, 0x1f776, 0x1e222, 0x1eee4, + 0x1e662, 0x1eee2, 0x1c468, 0x1e236, 0x1cce8, 0x1c464, 0x1dde8, 0x1cce4, + 0x1c462, 0x1dde4, 0x1cce2, 0x1dde2, 0x188e8, 0x1c476, 0x199e8, 0x188e4, + 0x1bbe8, 0x199e4, 0x188e2, 0x1bbe4, 0x199e2, 0x1bbe2, 0x111e8, 0x188f6, + 0x133e8, 0x111e4, 0x177e8, 0x133e4, 0x111e2, 0x177e4, 0x133e2, 0x177e2, + 0x111f6, 0x133f6, 0x1fb94, 0x172f8, 0x1b97e, 0x1fb92, 0x1727c, 0x1723e, + 0x1f314, 0x1317e, 0x1f734, 0x1f312, 0x1737e, 0x1f732, 0x1e214, 0x1e634, + 0x1e212, 0x1ee74, 0x1e632, 0x1ee72, 0x1c434, 0x1cc74, 0x1c432, 0x1dcf4, + 0x1cc72, 0x1dcf2, 0x18874, 0x198f4, 0x18872, 0x1b9f4, 0x198f2, 0x1b9f2, + 0x110f4, 0x131f4, 0x110f2, 0x173f4, 0x131f2, 0x173f2, 0x1fb8a, 0x1717c, + 0x1713e, 0x1f30a, 0x1f71a, 0x1e20a, 0x1e61a, 0x1ee3a, 0x1c41a, 0x1cc3a, + 0x1dc7a, 0x1883a, 0x1987a, 0x1b8fa, 0x1107a, 0x130fa, 0x171fa, 0x170be, + 0x1e150, 0x1f0ac, 0x1e148, 0x1f0a6, 0x1e144, 0x1e142, 0x1c2d0, 0x1e16c, + 0x1c2c8, 0x1e166, 0x1c2c4, 0x1c2c2, 0x185d0, 0x1c2ec, 0x185c8, 0x1c2e6, + 0x185c4, 0x185c2, 0x10bd0, 0x185ec, 0x10bc8, 0x185e6, 0x10bc4, 0x10bc2, + 0x10bec, 0x10be6, 0x1f1a8, 0x1f8d6, 0x11afc, 0x1f1a4, 0x11a7e, 0x1f1a2, + 0x1e128, 0x1f096, 0x1e368, 0x1e124, 0x1e364, 0x1e122, 0x1e362, 0x1c268, + 0x1e136, 0x1c6e8, 0x1c264, 0x1c6e4, 0x1c262, 0x1c6e2, 0x184e8, 0x1c276, + 0x18de8, 0x184e4, 0x18de4, 0x184e2, 0x18de2, 0x109e8, 0x184f6, 0x11be8, + 0x109e4, 0x11be4, 0x109e2, 0x11be2, 0x109f6, 0x11bf6, 0x1f9d4, 0x13af8, + 0x19d7e, 0x1f9d2, 0x13a7c, 0x13a3e, 0x1f194, 0x1197e, 0x1f3b4, 0x1f192, + 0x13b7e, 0x1f3b2, 0x1e114, 0x1e334, 0x1e112, 0x1e774, 0x1e332, 0x1e772, + 0x1c234, 0x1c674, 0x1c232, 0x1cef4, 0x1c672, 0x1cef2, 0x18474, 0x18cf4, + 0x18472, 0x19df4, 0x18cf2, 0x19df2, 0x108f4, 0x119f4, 0x108f2, 0x13bf4, + 0x119f2, 0x13bf2, 0x17af0, 0x1bd7c, 0x17a78, 0x1bd3e, 0x17a3c, 0x17a1e, + 0x1f9ca, 0x1397c, 0x1fbda, 0x17b7c, 0x1393e, 0x17b3e, 0x1f18a, 0x1f39a, + 0x1f7ba, 0x1e10a, 0x1e31a, 0x1e73a, 0x1ef7a, 0x1c21a, 0x1c63a, 0x1ce7a, + 0x1defa, 0x1843a, 0x18c7a, 0x19cfa, 0x1bdfa, 0x1087a, 0x118fa, 0x139fa, + 0x17978, 0x1bcbe, 0x1793c, 0x1791e, 0x138be, 0x179be, 0x178bc, 0x1789e, + 0x1785e, 0x1e0a8, 0x1e0a4, 0x1e0a2, 0x1c168, 0x1e0b6, 0x1c164, 0x1c162, + 0x182e8, 0x1c176, 0x182e4, 0x182e2, 0x105e8, 0x182f6, 0x105e4, 0x105e2, + 0x105f6, 0x1f0d4, 0x10d7e, 0x1f0d2, 0x1e094, 0x1e1b4, 0x1e092, 0x1e1b2, + 0x1c134, 0x1c374, 0x1c132, 0x1c372, 0x18274, 0x186f4, 0x18272, 0x186f2, + 0x104f4, 0x10df4, 0x104f2, 0x10df2, 0x1f8ea, 0x11d7c, 0x11d3e, 0x1f0ca, + 0x1f1da, 0x1e08a, 0x1e19a, 0x1e3ba, 0x1c11a, 0x1c33a, 0x1c77a, 0x1823a, + 0x1867a, 0x18efa, 0x1047a, 0x10cfa, 0x11dfa, 0x13d78, 0x19ebe, 0x13d3c, + 0x13d1e, 0x11cbe, 0x13dbe, 0x17d70, 0x1bebc, 0x17d38, 0x1be9e, 0x17d1c, + 0x17d0e, 0x13cbc, 0x17dbc, 0x13c9e, 0x17d9e, 0x17cb8, 0x1be5e, 0x17c9c, + 0x17c8e, 0x13c5e, 0x17cde, 0x17c5c, 0x17c4e, 0x17c2e, 0x1c0b4, 0x1c0b2, + 0x18174, 0x18172, 0x102f4, 0x102f2, 0x1e0da, 0x1c09a, 0x1c1ba, 0x1813a, + 0x1837a, 0x1027a, 0x106fa, 0x10ebe, 0x11ebc, 0x11e9e, 0x13eb8, 0x19f5e, + 0x13e9c, 0x13e8e, 0x11e5e, 0x13ede, 0x17eb0, 0x1bf5c, 0x17e98, 0x1bf4e, + 0x17e8c, 0x17e86, 0x13e5c, 0x17edc, 0x13e4e, 0x17ece, 0x17e58, 0x1bf2e, + 0x17e4c, 0x17e46, 0x13e2e, 0x17e6e, 0x17e2c, 0x17e26, 0x10f5e, 0x11f5c, + 0x11f4e, 0x13f58, 0x19fae, 0x13f4c, 0x13f46, 0x11f2e, 0x13f6e, 0x13f2c, + 0x13f26}, + {0x1abe0, 0x1d5f8, 0x153c0, 0x1a9f0, 0x1d4fc, 0x151e0, 0x1a8f8, 0x1d47e, + 0x150f0, 0x1a87c, 0x15078, 0x1fad0, 0x15be0, 0x1adf8, 0x1fac8, 0x159f0, + 0x1acfc, 0x1fac4, 0x158f8, 0x1ac7e, 0x1fac2, 0x1587c, 0x1f5d0, 0x1faec, + 0x15df8, 0x1f5c8, 0x1fae6, 0x15cfc, 0x1f5c4, 0x15c7e, 0x1f5c2, 0x1ebd0, + 0x1f5ec, 0x1ebc8, 0x1f5e6, 0x1ebc4, 0x1ebc2, 0x1d7d0, 0x1ebec, 0x1d7c8, + 0x1ebe6, 0x1d7c4, 0x1d7c2, 0x1afd0, 0x1d7ec, 0x1afc8, 0x1d7e6, 0x1afc4, + 0x14bc0, 0x1a5f0, 0x1d2fc, 0x149e0, 0x1a4f8, 0x1d27e, 0x148f0, 0x1a47c, + 0x14878, 0x1a43e, 0x1483c, 0x1fa68, 0x14df0, 0x1a6fc, 0x1fa64, 0x14cf8, + 0x1a67e, 0x1fa62, 0x14c7c, 0x14c3e, 0x1f4e8, 0x1fa76, 0x14efc, 0x1f4e4, + 0x14e7e, 0x1f4e2, 0x1e9e8, 0x1f4f6, 0x1e9e4, 0x1e9e2, 0x1d3e8, 0x1e9f6, + 0x1d3e4, 0x1d3e2, 0x1a7e8, 0x1d3f6, 0x1a7e4, 0x1a7e2, 0x145e0, 0x1a2f8, + 0x1d17e, 0x144f0, 0x1a27c, 0x14478, 0x1a23e, 0x1443c, 0x1441e, 0x1fa34, + 0x146f8, 0x1a37e, 0x1fa32, 0x1467c, 0x1463e, 0x1f474, 0x1477e, 0x1f472, + 0x1e8f4, 0x1e8f2, 0x1d1f4, 0x1d1f2, 0x1a3f4, 0x1a3f2, 0x142f0, 0x1a17c, + 0x14278, 0x1a13e, 0x1423c, 0x1421e, 0x1fa1a, 0x1437c, 0x1433e, 0x1f43a, + 0x1e87a, 0x1d0fa, 0x14178, 0x1a0be, 0x1413c, 0x1411e, 0x141be, 0x140bc, + 0x1409e, 0x12bc0, 0x195f0, 0x1cafc, 0x129e0, 0x194f8, 0x1ca7e, 0x128f0, + 0x1947c, 0x12878, 0x1943e, 0x1283c, 0x1f968, 0x12df0, 0x196fc, 0x1f964, + 0x12cf8, 0x1967e, 0x1f962, 0x12c7c, 0x12c3e, 0x1f2e8, 0x1f976, 0x12efc, + 0x1f2e4, 0x12e7e, 0x1f2e2, 0x1e5e8, 0x1f2f6, 0x1e5e4, 0x1e5e2, 0x1cbe8, + 0x1e5f6, 0x1cbe4, 0x1cbe2, 0x197e8, 0x1cbf6, 0x197e4, 0x197e2, 0x1b5e0, + 0x1daf8, 0x1ed7e, 0x169c0, 0x1b4f0, 0x1da7c, 0x168e0, 0x1b478, 0x1da3e, + 0x16870, 0x1b43c, 0x16838, 0x1b41e, 0x1681c, 0x125e0, 0x192f8, 0x1c97e, + 0x16de0, 0x124f0, 0x1927c, 0x16cf0, 0x1b67c, 0x1923e, 0x16c78, 0x1243c, + 0x16c3c, 0x1241e, 0x16c1e, 0x1f934, 0x126f8, 0x1937e, 0x1fb74, 0x1f932, + 0x16ef8, 0x1267c, 0x1fb72, 0x16e7c, 0x1263e, 0x16e3e, 0x1f274, 0x1277e, + 0x1f6f4, 0x1f272, 0x16f7e, 0x1f6f2, 0x1e4f4, 0x1edf4, 0x1e4f2, 0x1edf2, + 0x1c9f4, 0x1dbf4, 0x1c9f2, 0x1dbf2, 0x193f4, 0x193f2, 0x165c0, 0x1b2f0, + 0x1d97c, 0x164e0, 0x1b278, 0x1d93e, 0x16470, 0x1b23c, 0x16438, 0x1b21e, + 0x1641c, 0x1640e, 0x122f0, 0x1917c, 0x166f0, 0x12278, 0x1913e, 0x16678, + 0x1b33e, 0x1663c, 0x1221e, 0x1661e, 0x1f91a, 0x1237c, 0x1fb3a, 0x1677c, + 0x1233e, 0x1673e, 0x1f23a, 0x1f67a, 0x1e47a, 0x1ecfa, 0x1c8fa, 0x1d9fa, + 0x191fa, 0x162e0, 0x1b178, 0x1d8be, 0x16270, 0x1b13c, 0x16238, 0x1b11e, + 0x1621c, 0x1620e, 0x12178, 0x190be, 0x16378, 0x1213c, 0x1633c, 0x1211e, + 0x1631e, 0x121be, 0x163be, 0x16170, 0x1b0bc, 0x16138, 0x1b09e, 0x1611c, + 0x1610e, 0x120bc, 0x161bc, 0x1209e, 0x1619e, 0x160b8, 0x1b05e, 0x1609c, + 0x1608e, 0x1205e, 0x160de, 0x1605c, 0x1604e, 0x115e0, 0x18af8, 0x1c57e, + 0x114f0, 0x18a7c, 0x11478, 0x18a3e, 0x1143c, 0x1141e, 0x1f8b4, 0x116f8, + 0x18b7e, 0x1f8b2, 0x1167c, 0x1163e, 0x1f174, 0x1177e, 0x1f172, 0x1e2f4, + 0x1e2f2, 0x1c5f4, 0x1c5f2, 0x18bf4, 0x18bf2, 0x135c0, 0x19af0, 0x1cd7c, + 0x134e0, 0x19a78, 0x1cd3e, 0x13470, 0x19a3c, 0x13438, 0x19a1e, 0x1341c, + 0x1340e, 0x112f0, 0x1897c, 0x136f0, 0x11278, 0x1893e, 0x13678, 0x19b3e, + 0x1363c, 0x1121e, 0x1361e, 0x1f89a, 0x1137c, 0x1f9ba, 0x1377c, 0x1133e, + 0x1373e, 0x1f13a, 0x1f37a, 0x1e27a, 0x1e6fa, 0x1c4fa, 0x1cdfa, 0x189fa, + 0x1bae0, 0x1dd78, 0x1eebe, 0x174c0, 0x1ba70, 0x1dd3c, 0x17460, 0x1ba38, + 0x1dd1e, 0x17430, 0x1ba1c, 0x17418, 0x1ba0e, 0x1740c, 0x132e0, 0x19978, + 0x1ccbe, 0x176e0, 0x13270, 0x1993c, 0x17670, 0x1bb3c, 0x1991e, 0x17638, + 0x1321c, 0x1761c, 0x1320e, 0x1760e, 0x11178, 0x188be, 0x13378, 0x1113c, + 0x17778, 0x1333c, 0x1111e, 0x1773c, 0x1331e, 0x1771e, 0x111be, 0x133be, + 0x177be, 0x172c0, 0x1b970, 0x1dcbc, 0x17260, 0x1b938, 0x1dc9e, 0x17230, + 0x1b91c, 0x17218, 0x1b90e, 0x1720c, 0x17206, 0x13170, 0x198bc, 0x17370, + 0x13138, 0x1989e, 0x17338, 0x1b99e, 0x1731c, 0x1310e, 0x1730e, 0x110bc, + 0x131bc, 0x1109e, 0x173bc, 0x1319e, 0x1739e, 0x17160, 0x1b8b8, 0x1dc5e, + 0x17130, 0x1b89c, 0x17118, 0x1b88e, 0x1710c, 0x17106, 0x130b8, 0x1985e, + 0x171b8, 0x1309c, 0x1719c, 0x1308e, 0x1718e, 0x1105e, 0x130de, 0x171de, + 0x170b0, 0x1b85c, 0x17098, 0x1b84e, 0x1708c, 0x17086, 0x1305c, 0x170dc, + 0x1304e, 0x170ce, 0x17058, 0x1b82e, 0x1704c, 0x17046, 0x1302e, 0x1706e, + 0x1702c, 0x17026, 0x10af0, 0x1857c, 0x10a78, 0x1853e, 0x10a3c, 0x10a1e, + 0x10b7c, 0x10b3e, 0x1f0ba, 0x1e17a, 0x1c2fa, 0x185fa, 0x11ae0, 0x18d78, + 0x1c6be, 0x11a70, 0x18d3c, 0x11a38, 0x18d1e, 0x11a1c, 0x11a0e, 0x10978, + 0x184be, 0x11b78, 0x1093c, 0x11b3c, 0x1091e, 0x11b1e, 0x109be, 0x11bbe, + 0x13ac0, 0x19d70, 0x1cebc, 0x13a60, 0x19d38, 0x1ce9e, 0x13a30, 0x19d1c, + 0x13a18, 0x19d0e, 0x13a0c, 0x13a06, 0x11970, 0x18cbc, 0x13b70, 0x11938, + 0x18c9e, 0x13b38, 0x1191c, 0x13b1c, 0x1190e, 0x13b0e, 0x108bc, 0x119bc, + 0x1089e, 0x13bbc, 0x1199e, 0x13b9e, 0x1bd60, 0x1deb8, 0x1ef5e, 0x17a40, + 0x1bd30, 0x1de9c, 0x17a20, 0x1bd18, 0x1de8e, 0x17a10, 0x1bd0c, 0x17a08, + 0x1bd06, 0x17a04, 0x13960, 0x19cb8, 0x1ce5e, 0x17b60, 0x13930, 0x19c9c, + 0x17b30, 0x1bd9c, 0x19c8e, 0x17b18, 0x1390c, 0x17b0c, 0x13906, 0x17b06, + 0x118b8, 0x18c5e, 0x139b8, 0x1189c, 0x17bb8, 0x1399c, 0x1188e, 0x17b9c, + 0x1398e, 0x17b8e, 0x1085e, 0x118de, 0x139de, 0x17bde, 0x17940, 0x1bcb0, + 0x1de5c, 0x17920, 0x1bc98, 0x1de4e, 0x17910, 0x1bc8c, 0x17908, 0x1bc86, + 0x17904, 0x17902, 0x138b0, 0x19c5c, 0x179b0, 0x13898, 0x19c4e, 0x17998, + 0x1bcce, 0x1798c, 0x13886, 0x17986, 0x1185c, 0x138dc, 0x1184e, 0x179dc, + 0x138ce, 0x179ce, 0x178a0, 0x1bc58, 0x1de2e, 0x17890, 0x1bc4c, 0x17888, + 0x1bc46, 0x17884, 0x17882, 0x13858, 0x19c2e, 0x178d8, 0x1384c, 0x178cc, + 0x13846, 0x178c6, 0x1182e, 0x1386e, 0x178ee, 0x17850, 0x1bc2c, 0x17848, + 0x1bc26, 0x17844, 0x17842, 0x1382c, 0x1786c, 0x13826, 0x17866, 0x17828, + 0x1bc16, 0x17824, 0x17822, 0x13816, 0x17836, 0x10578, 0x182be, 0x1053c, + 0x1051e, 0x105be, 0x10d70, 0x186bc, 0x10d38, 0x1869e, 0x10d1c, 0x10d0e, + 0x104bc, 0x10dbc, 0x1049e, 0x10d9e, 0x11d60, 0x18eb8, 0x1c75e, 0x11d30, + 0x18e9c, 0x11d18, 0x18e8e, 0x11d0c, 0x11d06, 0x10cb8, 0x1865e, 0x11db8, + 0x10c9c, 0x11d9c, 0x10c8e, 0x11d8e, 0x1045e, 0x10cde, 0x11dde, 0x13d40, + 0x19eb0, 0x1cf5c, 0x13d20, 0x19e98, 0x1cf4e, 0x13d10, 0x19e8c, 0x13d08, + 0x19e86, 0x13d04, 0x13d02, 0x11cb0, 0x18e5c, 0x13db0, 0x11c98, 0x18e4e, + 0x13d98, 0x19ece, 0x13d8c, 0x11c86, 0x13d86, 0x10c5c, 0x11cdc, 0x10c4e, + 0x13ddc, 0x11cce, 0x13dce, 0x1bea0, 0x1df58, 0x1efae, 0x1be90, 0x1df4c, + 0x1be88, 0x1df46, 0x1be84, 0x1be82, 0x13ca0, 0x19e58, 0x1cf2e, 0x17da0, + 0x13c90, 0x19e4c, 0x17d90, 0x1becc, 0x19e46, 0x17d88, 0x13c84, 0x17d84, + 0x13c82, 0x17d82, 0x11c58, 0x18e2e, 0x13cd8, 0x11c4c, 0x17dd8, 0x13ccc, + 0x11c46, 0x17dcc, 0x13cc6, 0x17dc6, 0x10c2e, 0x11c6e, 0x13cee, 0x17dee, + 0x1be50, 0x1df2c, 0x1be48, 0x1df26, 0x1be44, 0x1be42, 0x13c50, 0x19e2c, + 0x17cd0, 0x13c48, 0x19e26, 0x17cc8, 0x1be66, 0x17cc4, 0x13c42, 0x17cc2, + 0x11c2c, 0x13c6c, 0x11c26, 0x17cec, 0x13c66, 0x17ce6, 0x1be28, 0x1df16, + 0x1be24, 0x1be22, 0x13c28, 0x19e16, 0x17c68, 0x13c24, 0x17c64, 0x13c22, + 0x17c62, 0x11c16, 0x13c36, 0x17c76, 0x1be14, 0x1be12, 0x13c14, 0x17c34, + 0x13c12, 0x17c32, 0x102bc, 0x1029e, 0x106b8, 0x1835e, 0x1069c, 0x1068e, + 0x1025e, 0x106de, 0x10eb0, 0x1875c, 0x10e98, 0x1874e, 0x10e8c, 0x10e86, + 0x1065c, 0x10edc, 0x1064e, 0x10ece, 0x11ea0, 0x18f58, 0x1c7ae, 0x11e90, + 0x18f4c, 0x11e88, 0x18f46, 0x11e84, 0x11e82, 0x10e58, 0x1872e, 0x11ed8, + 0x18f6e, 0x11ecc, 0x10e46, 0x11ec6, 0x1062e, 0x10e6e, 0x11eee, 0x19f50, + 0x1cfac, 0x19f48, 0x1cfa6, 0x19f44, 0x19f42, 0x11e50, 0x18f2c, 0x13ed0, + 0x19f6c, 0x18f26, 0x13ec8, 0x11e44, 0x13ec4, 0x11e42, 0x13ec2, 0x10e2c, + 0x11e6c, 0x10e26, 0x13eec, 0x11e66, 0x13ee6, 0x1dfa8, 0x1efd6, 0x1dfa4, + 0x1dfa2, 0x19f28, 0x1cf96, 0x1bf68, 0x19f24, 0x1bf64, 0x19f22, 0x1bf62, + 0x11e28, 0x18f16, 0x13e68, 0x11e24, 0x17ee8, 0x13e64, 0x11e22, 0x17ee4, + 0x13e62, 0x17ee2, 0x10e16, 0x11e36, 0x13e76, 0x17ef6, 0x1df94, 0x1df92, + 0x19f14, 0x1bf34, 0x19f12, 0x1bf32, 0x11e14, 0x13e34, 0x11e12, 0x17e74, + 0x13e32, 0x17e72, 0x1df8a, 0x19f0a, 0x1bf1a, 0x11e0a, 0x13e1a, 0x17e3a, + 0x1035c, 0x1034e, 0x10758, 0x183ae, 0x1074c, 0x10746, 0x1032e, 0x1076e, + 0x10f50, 0x187ac, 0x10f48, 0x187a6, 0x10f44, 0x10f42, 0x1072c, 0x10f6c, + 0x10726, 0x10f66, 0x18fa8, 0x1c7d6, 0x18fa4, 0x18fa2, 0x10f28, 0x18796, + 0x11f68, 0x18fb6, 0x11f64, 0x10f22, 0x11f62, 0x10716, 0x10f36, 0x11f76, + 0x1cfd4, 0x1cfd2, 0x18f94, 0x19fb4, 0x18f92, 0x19fb2, 0x10f14, 0x11f34, + 0x10f12, 0x13f74, 0x11f32, 0x13f72, 0x1cfca, 0x18f8a, 0x19f9a, 0x10f0a, + 0x11f1a, 0x13f3a, 0x103ac, 0x103a6, 0x107a8, 0x183d6, 0x107a4, 0x107a2, + 0x10396, 0x107b6, 0x187d4, 0x187d2, 0x10794, 0x10fb4, 0x10792, 0x10fb2, + 0x1c7ea}}; +FX_FLOAT CBC_PDF417::PREFERRED_RATIO = 3.0f; +FX_FLOAT CBC_PDF417::DEFAULT_MODULE_WIDTH = 0.357f; +FX_FLOAT CBC_PDF417::HEIGHT = 2.0f; +CBC_PDF417::CBC_PDF417() { + m_compact = FALSE; + m_compaction = AUTO; + m_minCols = 1; + m_maxCols = 30; + m_maxRows = 90; + m_minRows = 3; + m_barcodeMatrix = NULL; +} +CBC_PDF417::CBC_PDF417(FX_BOOL compact) { + m_compact = compact; + m_compaction = AUTO; + m_minCols = 1; + m_maxCols = 30; + m_maxRows = 90; + m_minRows = 3; + m_barcodeMatrix = NULL; +} +CBC_PDF417::~CBC_PDF417() { + if (m_barcodeMatrix) { + delete m_barcodeMatrix; + } +} +CBC_BarcodeMatrix* CBC_PDF417::getBarcodeMatrix() { + return m_barcodeMatrix; +} +void CBC_PDF417::generateBarcodeLogic(CFX_WideString msg, + int32_t errorCorrectionLevel, + int32_t& e) { + int32_t errorCorrectionCodeWords = + CBC_PDF417ErrorCorrection::getErrorCorrectionCodewordCount( + errorCorrectionLevel, e); + BC_EXCEPTION_CHECK_ReturnVoid(e); + CFX_WideString highLevel = + CBC_PDF417HighLevelEncoder::encodeHighLevel(msg, m_compaction, e); + BC_EXCEPTION_CHECK_ReturnVoid(e); + int32_t sourceCodeWords = highLevel.GetLength(); + CFX_Int32Array* dimension = + determineDimensions(sourceCodeWords, errorCorrectionCodeWords, e); + BC_EXCEPTION_CHECK_ReturnVoid(e); + int32_t cols = dimension->GetAt(0); + int32_t rows = dimension->GetAt(1); + delete dimension; + int32_t pad = getNumberOfPadCodewords(sourceCodeWords, + errorCorrectionCodeWords, cols, rows); + if (sourceCodeWords + errorCorrectionCodeWords + 1 > 929) { + e = BCExceptionEncodedMessageContainsTooManyCodeWords; + return; + } + int32_t n = sourceCodeWords + pad + 1; + CFX_WideString sb; + sb += (FX_WCHAR)n; + sb += highLevel; + for (int32_t i = 0; i < pad; i++) { + sb += (FX_WCHAR)900; + } + CFX_WideString dataCodewords(sb); + CFX_WideString ec = CBC_PDF417ErrorCorrection::generateErrorCorrection( + dataCodewords, errorCorrectionLevel, e); + BC_EXCEPTION_CHECK_ReturnVoid(e); + CFX_WideString fullCodewords = dataCodewords + ec; + m_barcodeMatrix = new CBC_BarcodeMatrix(rows, cols); + encodeLowLevel(fullCodewords, cols, rows, errorCorrectionLevel, + m_barcodeMatrix); +} +void CBC_PDF417::setDimensions(int32_t maxCols, + int32_t minCols, + int32_t maxRows, + int32_t minRows) { + m_maxCols = maxCols; + m_minCols = minCols; + m_maxRows = maxRows; + m_minRows = minRows; +} +void CBC_PDF417::setCompaction(Compaction compaction) { + m_compaction = compaction; +} +void CBC_PDF417::setCompact(FX_BOOL compact) { + m_compact = compact; +} +int32_t CBC_PDF417::calculateNumberOfRows(int32_t m, int32_t k, int32_t c) { + int32_t r = ((m + 1 + k) / c) + 1; + if (c * r >= (m + 1 + k + c)) { + r--; + } + return r; +} +int32_t CBC_PDF417::getNumberOfPadCodewords(int32_t m, + int32_t k, + int32_t c, + int32_t r) { + int32_t n = c * r - k; + return n > m + 1 ? n - m - 1 : 0; +} +void CBC_PDF417::encodeChar(int32_t pattern, + int32_t len, + CBC_BarcodeRow* logic) { + int32_t map = 1 << (len - 1); + FX_BOOL last = ((pattern & map) != 0); + int32_t width = 0; + for (int32_t i = 0; i < len; i++) { + FX_BOOL black = ((pattern & map) != 0); + if (last == black) { + width++; + } else { + logic->addBar(last, width); + last = black; + width = 1; + } + map >>= 1; + } + logic->addBar(last, width); +} +void CBC_PDF417::encodeLowLevel(CFX_WideString fullCodewords, + int32_t c, + int32_t r, + int32_t errorCorrectionLevel, + CBC_BarcodeMatrix* logic) { + int32_t idx = 0; + for (int32_t y = 0; y < r; y++) { + int32_t cluster = y % 3; + logic->startRow(); + encodeChar(START_PATTERN, 17, logic->getCurrentRow()); + int32_t left; + int32_t right; + if (cluster == 0) { + left = (30 * (y / 3)) + ((r - 1) / 3); + right = (30 * (y / 3)) + (c - 1); + } else if (cluster == 1) { + left = (30 * (y / 3)) + (errorCorrectionLevel * 3) + ((r - 1) % 3); + right = (30 * (y / 3)) + ((r - 1) / 3); + } else { + left = (30 * (y / 3)) + (c - 1); + right = (30 * (y / 3)) + (errorCorrectionLevel * 3) + ((r - 1) % 3); + } + int32_t pattern = CODEWORD_TABLE[cluster][left]; + encodeChar(pattern, 17, logic->getCurrentRow()); + for (int32_t x = 0; x < c; x++) { + pattern = CODEWORD_TABLE[cluster][fullCodewords.GetAt(idx)]; + encodeChar(pattern, 17, logic->getCurrentRow()); + idx++; + } + if (m_compact) { + encodeChar(STOP_PATTERN, 1, logic->getCurrentRow()); + } else { + pattern = CODEWORD_TABLE[cluster][right]; + encodeChar(pattern, 17, logic->getCurrentRow()); + encodeChar(STOP_PATTERN, 18, logic->getCurrentRow()); + } + } +} +CFX_Int32Array* CBC_PDF417::determineDimensions( + int32_t sourceCodeWords, + int32_t errorCorrectionCodeWords, + int32_t& e) { + FX_FLOAT ratio = 0.0f; + CFX_Int32Array* dimension = NULL; + for (int32_t cols = m_minCols; cols <= m_maxCols; cols++) { + int32_t rows = + calculateNumberOfRows(sourceCodeWords, errorCorrectionCodeWords, cols); + if (rows < m_minRows) { + break; + } + if (rows > m_maxRows) { + continue; + } + FX_FLOAT newRatio = + ((17 * cols + 69) * DEFAULT_MODULE_WIDTH) / (rows * HEIGHT); + if (dimension && + fabsf(newRatio - PREFERRED_RATIO) > fabsf(ratio - PREFERRED_RATIO)) { + continue; + } + ratio = newRatio; + if (dimension) { + delete dimension; + } + dimension = new CFX_Int32Array; + dimension->Add(cols); + dimension->Add(rows); + } + if (dimension == NULL) { + int32_t rows = calculateNumberOfRows(sourceCodeWords, + errorCorrectionCodeWords, m_minCols); + if (rows < m_minRows) { + dimension = new CFX_Int32Array; + dimension->Add(m_minCols); + dimension->Add(m_minRows); + } else if (rows >= 3 && rows <= 90) { + dimension = new CFX_Int32Array; + dimension->Add(m_minCols); + dimension->Add(rows); + } + } + if (dimension == NULL) { + e = BCExceptionUnableToFitMessageInColumns; + return NULL; + } + return dimension; +} diff --git a/xfa/fxbarcode/pdf417/BC_PDF417.h b/xfa/fxbarcode/pdf417/BC_PDF417.h new file mode 100644 index 0000000000..fe279db21b --- /dev/null +++ b/xfa/fxbarcode/pdf417/BC_PDF417.h @@ -0,0 +1,64 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef XFA_FXBARCODE_PDF417_BC_PDF417_H_ +#define XFA_FXBARCODE_PDF417_BC_PDF417_H_ + +#include "core/include/fxcrt/fx_basic.h" +#include "xfa/fxbarcode/pdf417/BC_PDF417Compaction.h" + +class CBC_BarcodeRow; +class CBC_BarcodeMatrix; + +class CBC_PDF417 { + public: + CBC_PDF417(); + CBC_PDF417(FX_BOOL compact); + virtual ~CBC_PDF417(); + CBC_BarcodeMatrix* getBarcodeMatrix(); + void generateBarcodeLogic(CFX_WideString msg, + int32_t errorCorrectionLevel, + int32_t& e); + void setDimensions(int32_t maxCols, + int32_t minCols, + int32_t maxRows, + int32_t minRows); + void setCompaction(Compaction compaction); + void setCompact(FX_BOOL compact); + + private: + static int32_t START_PATTERN; + static int32_t STOP_PATTERN; + static int32_t CODEWORD_TABLE[][1000]; + static FX_FLOAT PREFERRED_RATIO; + static FX_FLOAT DEFAULT_MODULE_WIDTH; + static FX_FLOAT HEIGHT; + CBC_BarcodeMatrix* m_barcodeMatrix; + FX_BOOL m_compact; + Compaction m_compaction; + int32_t m_minCols; + int32_t m_maxCols; + int32_t m_maxRows; + int32_t m_minRows; + + private: + static int32_t calculateNumberOfRows(int32_t m, int32_t k, int32_t c); + static int32_t getNumberOfPadCodewords(int32_t m, + int32_t k, + int32_t c, + int32_t r); + static void encodeChar(int32_t pattern, int32_t len, CBC_BarcodeRow* logic); + void encodeLowLevel(CFX_WideString fullCodewords, + int32_t c, + int32_t r, + int32_t errorCorrectionLevel, + CBC_BarcodeMatrix* logic); + CFX_Int32Array* determineDimensions(int32_t sourceCodeWords, + int32_t errorCorrectionCodeWords, + int32_t& e); +}; + +#endif // XFA_FXBARCODE_PDF417_BC_PDF417_H_ diff --git a/xfa/fxbarcode/pdf417/BC_PDF417BarcodeMatrix.cpp b/xfa/fxbarcode/pdf417/BC_PDF417BarcodeMatrix.cpp new file mode 100644 index 0000000000..47255fac71 --- /dev/null +++ b/xfa/fxbarcode/pdf417/BC_PDF417BarcodeMatrix.cpp @@ -0,0 +1,90 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com +// Original code is licensed as follows: +/* + * Copyright 2011 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "xfa/fxbarcode/pdf417/BC_PDF417BarcodeMatrix.h" +#include "xfa/fxbarcode/pdf417/BC_PDF417BarcodeRow.h" + +CBC_BarcodeMatrix::CBC_BarcodeMatrix(int32_t height, int32_t width) { + m_matrix.SetSize(height + 2); + for (int32_t i = 0, matrixLength = m_matrix.GetSize(); i < matrixLength; + i++) { + m_matrix[i] = new CBC_BarcodeRow((width + 4) * 17 + 1); + } + m_width = width * 17; + m_height = height + 2; + m_currentRow = 0; + m_outHeight = 0; + m_outWidth = 0; +} +CBC_BarcodeMatrix::~CBC_BarcodeMatrix() { + for (int32_t i = 0; i < m_matrix.GetSize(); i++) { + delete (CBC_BarcodeRow*)m_matrix.GetAt(i); + } + m_matrix.RemoveAll(); + m_matrixOut.RemoveAll(); +} +void CBC_BarcodeMatrix::set(int32_t x, int32_t y, uint8_t value) { + ((CBC_BarcodeRow*)m_matrix[y])->set(x, value); +} +void CBC_BarcodeMatrix::setMatrix(int32_t x, int32_t y, FX_BOOL black) { + set(x, y, (uint8_t)(black ? 1 : 0)); +} +void CBC_BarcodeMatrix::startRow() { + ++m_currentRow; +} +CBC_BarcodeRow* CBC_BarcodeMatrix::getCurrentRow() { + return (CBC_BarcodeRow*)m_matrix[m_currentRow]; +} +int32_t CBC_BarcodeMatrix::getWidth() { + return m_outWidth; +} +int32_t CBC_BarcodeMatrix::getHeight() { + return m_outHeight; +} +CFX_ByteArray& CBC_BarcodeMatrix::getMatrix() { + return getScaledMatrix(1, 1); +} +CFX_ByteArray& CBC_BarcodeMatrix::getScaledMatrix(int32_t scale) { + return getScaledMatrix(scale, scale); +} +CFX_ByteArray& CBC_BarcodeMatrix::getScaledMatrix(int32_t xScale, + int32_t yScale) { + int32_t yMax = m_height * yScale; + CFX_ByteArray bytearray; + bytearray.Copy(((CBC_BarcodeRow*)m_matrix[0])->getScaledRow(xScale)); + int32_t xMax = bytearray.GetSize(); + m_matrixOut.SetSize(xMax * yMax); + m_outWidth = xMax; + m_outHeight = yMax; + int32_t k = 0; + for (int32_t i = 0; i < yMax; i++) { + if (i != 0) { + bytearray.Copy( + ((CBC_BarcodeRow*)m_matrix[i / yScale])->getScaledRow(xScale)); + } + k = i * xMax; + for (int32_t l = 0; l < xMax; l++) { + m_matrixOut[k + l] = bytearray.GetAt(l); + } + } + return m_matrixOut; +} diff --git a/xfa/fxbarcode/pdf417/BC_PDF417BarcodeMatrix.h b/xfa/fxbarcode/pdf417/BC_PDF417BarcodeMatrix.h new file mode 100644 index 0000000000..21ee44b65f --- /dev/null +++ b/xfa/fxbarcode/pdf417/BC_PDF417BarcodeMatrix.h @@ -0,0 +1,38 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef XFA_FXBARCODE_PDF417_BC_PDF417BARCODEMATRIX_H_ +#define XFA_FXBARCODE_PDF417_BC_PDF417BARCODEMATRIX_H_ + +#include "core/include/fxcrt/fx_basic.h" + +class CBC_BarcodeRow; +class CBC_BarcodeMatrix { + public: + CBC_BarcodeMatrix(); + CBC_BarcodeMatrix(int32_t height, int32_t width); + virtual ~CBC_BarcodeMatrix(); + void set(int32_t x, int32_t y, uint8_t value); + void setMatrix(int32_t x, int32_t y, FX_BOOL black); + void startRow(); + CBC_BarcodeRow* getCurrentRow(); + CFX_ByteArray& getMatrix(); + CFX_ByteArray& getScaledMatrix(int32_t scale); + CFX_ByteArray& getScaledMatrix(int32_t xScale, int32_t yScale); + int32_t getWidth(); + int32_t getHeight(); + + private: + CFX_PtrArray m_matrix; + CFX_ByteArray m_matrixOut; + int32_t m_currentRow; + int32_t m_height; + int32_t m_width; + int32_t m_outWidth; + int32_t m_outHeight; +}; + +#endif // XFA_FXBARCODE_PDF417_BC_PDF417BARCODEMATRIX_H_ diff --git a/xfa/fxbarcode/pdf417/BC_PDF417BarcodeMetadata.cpp b/xfa/fxbarcode/pdf417/BC_PDF417BarcodeMetadata.cpp new file mode 100644 index 0000000000..ac59c6ef94 --- /dev/null +++ b/xfa/fxbarcode/pdf417/BC_PDF417BarcodeMetadata.cpp @@ -0,0 +1,50 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com +// Original code is licensed as follows: +/* + * Copyright 2013 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "xfa/fxbarcode/pdf417/BC_PDF417BarcodeMetadata.h" + +CBC_BarcodeMetadata::CBC_BarcodeMetadata(int32_t columnCount, + int32_t rowCountUpperPart, + int32_t rowCountLowerPart, + int32_t errorCorrectionLevel) { + m_columnCount = columnCount; + m_rowCountUpperPart = rowCountUpperPart; + m_rowCountLowerPart = rowCountLowerPart; + m_errorCorrectionLevel = errorCorrectionLevel; + m_rowCount = m_rowCountUpperPart + m_rowCountLowerPart; +} +CBC_BarcodeMetadata::~CBC_BarcodeMetadata() {} +int32_t CBC_BarcodeMetadata::getColumnCount() { + return m_columnCount; +} +int32_t CBC_BarcodeMetadata::getErrorCorrectionLevel() { + return m_errorCorrectionLevel; +} +int32_t CBC_BarcodeMetadata::getRowCount() { + return m_rowCount; +} +int32_t CBC_BarcodeMetadata::getRowCountUpperPart() { + return m_rowCountUpperPart; +} +int32_t CBC_BarcodeMetadata::getRowCountLowerPart() { + return m_rowCountLowerPart; +} diff --git a/xfa/fxbarcode/pdf417/BC_PDF417BarcodeMetadata.h b/xfa/fxbarcode/pdf417/BC_PDF417BarcodeMetadata.h new file mode 100644 index 0000000000..2b398f13f6 --- /dev/null +++ b/xfa/fxbarcode/pdf417/BC_PDF417BarcodeMetadata.h @@ -0,0 +1,33 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef XFA_FXBARCODE_PDF417_BC_PDF417BARCODEMETADATA_H_ +#define XFA_FXBARCODE_PDF417_BC_PDF417BARCODEMETADATA_H_ + +#include <stdint.h> + +class CBC_BarcodeMetadata { + public: + CBC_BarcodeMetadata(int32_t columnCount, + int32_t rowCountUpperPart, + int32_t rowCountLowerPart, + int32_t errorCorrectionLevel); + virtual ~CBC_BarcodeMetadata(); + int32_t getColumnCount(); + int32_t getErrorCorrectionLevel(); + int32_t getRowCount(); + int32_t getRowCountUpperPart(); + int32_t getRowCountLowerPart(); + + private: + int32_t m_columnCount; + int32_t m_errorCorrectionLevel; + int32_t m_rowCountUpperPart; + int32_t m_rowCountLowerPart; + int32_t m_rowCount; +}; + +#endif // XFA_FXBARCODE_PDF417_BC_PDF417BARCODEMETADATA_H_ diff --git a/xfa/fxbarcode/pdf417/BC_PDF417BarcodeRow.cpp b/xfa/fxbarcode/pdf417/BC_PDF417BarcodeRow.cpp new file mode 100644 index 0000000000..6f88b33877 --- /dev/null +++ b/xfa/fxbarcode/pdf417/BC_PDF417BarcodeRow.cpp @@ -0,0 +1,53 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com +// Original code is licensed as follows: +/* + * Copyright 2011 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "xfa/fxbarcode/pdf417/BC_PDF417BarcodeRow.h" + +CBC_BarcodeRow::CBC_BarcodeRow(int32_t width) { + m_row.SetSize(width); + m_currentLocation = 0; +} +CBC_BarcodeRow::~CBC_BarcodeRow() { + m_output.RemoveAll(); + m_row.RemoveAll(); +} +void CBC_BarcodeRow::set(int32_t x, uint8_t value) { + m_row.SetAt(x, value); +} +void CBC_BarcodeRow::set(int32_t x, FX_BOOL black) { + m_row.SetAt(x, (uint8_t)(black ? 1 : 0)); +} +void CBC_BarcodeRow::addBar(FX_BOOL black, int32_t width) { + for (int32_t ii = 0; ii < width; ii++) { + set(m_currentLocation++, black); + } +} +CFX_ByteArray& CBC_BarcodeRow::getRow() { + return m_row; +} +CFX_ByteArray& CBC_BarcodeRow::getScaledRow(int32_t scale) { + m_output.SetSize(m_row.GetSize() * scale); + for (int32_t i = 0; i < m_output.GetSize(); i++) { + m_output[i] = (m_row[i / scale]); + } + return m_output; +} diff --git a/xfa/fxbarcode/pdf417/BC_PDF417BarcodeRow.h b/xfa/fxbarcode/pdf417/BC_PDF417BarcodeRow.h new file mode 100644 index 0000000000..007876a93c --- /dev/null +++ b/xfa/fxbarcode/pdf417/BC_PDF417BarcodeRow.h @@ -0,0 +1,28 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef XFA_FXBARCODE_PDF417_BC_PDF417BARCODEROW_H_ +#define XFA_FXBARCODE_PDF417_BC_PDF417BARCODEROW_H_ + +#include "core/include/fxcrt/fx_basic.h" + +class CBC_BarcodeRow { + public: + CBC_BarcodeRow(int32_t width); + virtual ~CBC_BarcodeRow(); + void set(int32_t x, uint8_t value); + void set(int32_t x, FX_BOOL black); + void addBar(FX_BOOL black, int32_t width); + CFX_ByteArray& getRow(); + CFX_ByteArray& getScaledRow(int32_t scale); + + private: + CFX_ByteArray m_row; + CFX_ByteArray m_output; + int32_t m_currentLocation; +}; + +#endif // XFA_FXBARCODE_PDF417_BC_PDF417BARCODEROW_H_ diff --git a/xfa/fxbarcode/pdf417/BC_PDF417BarcodeValue.cpp b/xfa/fxbarcode/pdf417/BC_PDF417BarcodeValue.cpp new file mode 100644 index 0000000000..eb89546b5c --- /dev/null +++ b/xfa/fxbarcode/pdf417/BC_PDF417BarcodeValue.cpp @@ -0,0 +1,61 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com +// Original code is licensed as follows: +/* + * Copyright 2013 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "xfa/fxbarcode/pdf417/BC_PDF417BarcodeValue.h" +#include "xfa/fxbarcode/pdf417/BC_PDF417Common.h" + +CBC_BarcodeValue::CBC_BarcodeValue() {} +CBC_BarcodeValue::~CBC_BarcodeValue() {} +void CBC_BarcodeValue::setValue(int32_t value) { + int32_t confidence = 0; + for (int32_t i = 0; i < m_keys.GetSize(); i++) { + if (m_keys.GetAt(i) == value) { + confidence = m_values.GetAt(i); + m_values.SetAt(i, confidence + 1); + return; + } + } + confidence = 1; + m_keys.Add(value); + m_values.Add(confidence); +} +CFX_Int32Array* CBC_BarcodeValue::getValue() { + int32_t maxConfidence = -1; + CFX_Int32Array* result = new CFX_Int32Array; + for (int32_t i = 0; i < m_keys.GetSize(); i++) { + if (m_values.GetAt(i) > maxConfidence) { + maxConfidence = m_values.GetAt(i); + result->RemoveAll(); + result->Add(m_keys.GetAt(i)); + } else if (m_values.GetAt(i) == maxConfidence) { + result->Add(m_keys.GetAt(i)); + } + } + return result; +} +int32_t CBC_BarcodeValue::getConfidence(int32_t value) { + for (int32_t i = 0; i < m_keys.GetSize(); i++) + if (m_keys.GetAt(i) == value) { + return m_values.GetAt(i); + } + return -1; +} diff --git a/xfa/fxbarcode/pdf417/BC_PDF417BarcodeValue.h b/xfa/fxbarcode/pdf417/BC_PDF417BarcodeValue.h new file mode 100644 index 0000000000..e99fb84cba --- /dev/null +++ b/xfa/fxbarcode/pdf417/BC_PDF417BarcodeValue.h @@ -0,0 +1,25 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef XFA_FXBARCODE_PDF417_BC_PDF417BARCODEVALUE_H_ +#define XFA_FXBARCODE_PDF417_BC_PDF417BARCODEVALUE_H_ + +#include "core/include/fxcrt/fx_basic.h" + +class CBC_BarcodeValue { + public: + CBC_BarcodeValue(); + virtual ~CBC_BarcodeValue(); + void setValue(int32_t value); + CFX_Int32Array* getValue(); + int32_t getConfidence(int32_t value); + + private: + CFX_Int32Array m_keys; + CFX_Int32Array m_values; +}; + +#endif // XFA_FXBARCODE_PDF417_BC_PDF417BARCODEVALUE_H_ diff --git a/xfa/fxbarcode/pdf417/BC_PDF417BoundingBox.cpp b/xfa/fxbarcode/pdf417/BC_PDF417BoundingBox.cpp new file mode 100644 index 0000000000..c8328ab1c6 --- /dev/null +++ b/xfa/fxbarcode/pdf417/BC_PDF417BoundingBox.cpp @@ -0,0 +1,207 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com +// Original code is licensed as follows: +/* + * Copyright 2013 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "xfa/fxbarcode/BC_ResultPoint.h" +#include "xfa/fxbarcode/common/BC_CommonBitMatrix.h" +#include "xfa/fxbarcode/pdf417/BC_PDF417BoundingBox.h" +#include "xfa/fxbarcode/utils.h" + +CBC_BoundingBox::CBC_BoundingBox(CBC_CommonBitMatrix* image, + CBC_ResultPoint* topLeft, + CBC_ResultPoint* bottomLeft, + CBC_ResultPoint* topRight, + CBC_ResultPoint* bottomRight, + int32_t& e) { + if ((topLeft == NULL && topRight == NULL) || + (bottomLeft == NULL && bottomRight == NULL) || + (topLeft && bottomLeft == NULL) || (topRight && bottomRight == NULL)) { + e = BCExceptionNotFoundInstance; + } + init(image, topLeft, bottomLeft, topRight, bottomRight); +} +CBC_BoundingBox::CBC_BoundingBox(CBC_BoundingBox* boundingBox) { + init(boundingBox->m_image, boundingBox->m_topLeft, boundingBox->m_bottomLeft, + boundingBox->m_topRight, boundingBox->m_bottomRight); +} +CBC_BoundingBox::~CBC_BoundingBox() { + if (m_topLeft) { + delete m_topLeft; + } + if (m_bottomLeft) { + delete m_bottomLeft; + } + if (m_topRight) { + delete m_topRight; + } + if (m_bottomRight) { + delete m_bottomRight; + } +} +CBC_BoundingBox* CBC_BoundingBox::merge(CBC_BoundingBox* leftBox, + CBC_BoundingBox* rightBox, + int32_t& e) { + CBC_BoundingBox* boundingBox = NULL; + if (leftBox == NULL) { + boundingBox = new CBC_BoundingBox(rightBox); + return boundingBox; + } + if (rightBox == NULL) { + boundingBox = new CBC_BoundingBox(leftBox); + return boundingBox; + } + boundingBox = new CBC_BoundingBox(leftBox->m_image, leftBox->m_topLeft, + leftBox->m_bottomLeft, rightBox->m_topRight, + rightBox->m_bottomRight, e); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + return boundingBox; +} +CBC_BoundingBox* CBC_BoundingBox::addMissingRows(int32_t missingStartRows, + int32_t missingEndRows, + FX_BOOL isLeft, + int32_t& e) { + CBC_ResultPoint* newTopLeft = m_topLeft; + CBC_ResultPoint* newBottomLeft = m_bottomLeft; + CBC_ResultPoint* newTopRight = m_topRight; + CBC_ResultPoint* newBottomRight = m_bottomRight; + CBC_ResultPoint* newTop = NULL; + CBC_ResultPoint* newBottom = NULL; + if (missingStartRows > 0) { + CBC_ResultPoint* top = isLeft ? m_topLeft : m_topRight; + int32_t newMinY = (int32_t)top->GetY() - missingStartRows; + if (newMinY < 0) { + newMinY = 0; + } + newTop = new CBC_ResultPoint((FX_FLOAT)top->GetX(), (FX_FLOAT)newMinY); + if (isLeft) { + newTopLeft = newTop; + } else { + newTopRight = newTop; + } + } + if (missingEndRows > 0) { + CBC_ResultPoint* bottom = isLeft ? m_bottomLeft : m_bottomRight; + int32_t newMaxY = (int32_t)bottom->GetY() + missingEndRows; + if (newMaxY >= m_image->GetHeight()) { + newMaxY = m_image->GetHeight() - 1; + } + newBottom = + new CBC_ResultPoint((FX_FLOAT)bottom->GetX(), (FX_FLOAT)newMaxY); + if (isLeft) { + newBottomLeft = newBottom; + } else { + newBottomRight = newBottom; + } + } + calculateMinMaxValues(); + CBC_BoundingBox* boundingBox = new CBC_BoundingBox( + m_image, newTopLeft, newBottomLeft, newTopRight, newBottomRight, e); + delete newTop; + delete newBottom; + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + return boundingBox; +} +void CBC_BoundingBox::setTopRight(CBC_ResultPoint topRight) { + if (m_topRight) { + delete m_topRight; + } + m_topRight = new CBC_ResultPoint(topRight.GetX(), topRight.GetY()); + calculateMinMaxValues(); +} +void CBC_BoundingBox::setBottomRight(CBC_ResultPoint bottomRight) { + if (m_bottomRight) { + delete m_bottomRight; + } + m_bottomRight = new CBC_ResultPoint(bottomRight.GetX(), bottomRight.GetY()); + calculateMinMaxValues(); +} +int32_t CBC_BoundingBox::getMinX() { + return m_minX; +} +int32_t CBC_BoundingBox::getMaxX() { + return m_maxX; +} +int32_t CBC_BoundingBox::getMinY() { + return m_minY; +} +int32_t CBC_BoundingBox::getMaxY() { + return m_maxY; +} +CBC_ResultPoint* CBC_BoundingBox::getTopLeft() { + return m_topLeft; +} +CBC_ResultPoint* CBC_BoundingBox::getTopRight() { + return m_topRight; +} +CBC_ResultPoint* CBC_BoundingBox::getBottomLeft() { + return m_bottomLeft; +} +CBC_ResultPoint* CBC_BoundingBox::getBottomRight() { + return m_bottomRight; +} +void CBC_BoundingBox::init(CBC_CommonBitMatrix* image, + CBC_ResultPoint* topLeft, + CBC_ResultPoint* bottomLeft, + CBC_ResultPoint* topRight, + CBC_ResultPoint* bottomRight) { + m_topLeft = NULL; + m_bottomLeft = NULL; + m_topRight = NULL; + m_bottomRight = NULL; + m_image = image; + if (topLeft) { + m_topLeft = new CBC_ResultPoint(topLeft->GetX(), topLeft->GetY()); + } + if (bottomLeft) { + m_bottomLeft = new CBC_ResultPoint(bottomLeft->GetX(), bottomLeft->GetY()); + } + if (topRight) { + m_topRight = new CBC_ResultPoint(topRight->GetX(), topRight->GetY()); + } + if (bottomRight) { + m_bottomRight = + new CBC_ResultPoint(bottomRight->GetX(), bottomRight->GetY()); + } + calculateMinMaxValues(); +} +void CBC_BoundingBox::calculateMinMaxValues() { + if (m_topLeft == NULL) { + m_topLeft = new CBC_ResultPoint(0, m_topRight->GetY()); + m_bottomLeft = new CBC_ResultPoint(0, m_bottomRight->GetY()); + } else if (m_topRight == NULL) { + m_topRight = new CBC_ResultPoint((FX_FLOAT)m_image->GetWidth() - 1, + (FX_FLOAT)m_topLeft->GetY()); + m_bottomRight = new CBC_ResultPoint((FX_FLOAT)m_image->GetWidth() - 1, + (FX_FLOAT)m_bottomLeft->GetY()); + } + m_minX = (int32_t)(m_topLeft->GetX() < m_bottomLeft->GetX() + ? m_topLeft->GetX() + : m_bottomLeft->GetX()); + m_maxX = (int32_t)(m_topRight->GetX() > m_bottomRight->GetX() + ? m_topRight->GetX() + : m_bottomRight->GetX()); + m_minY = + (int32_t)(m_topLeft->GetY() < m_topRight->GetY() ? m_topLeft->GetY() + : m_topRight->GetY()); + m_maxY = (int32_t)(m_bottomLeft->GetY() > m_bottomRight->GetY() + ? m_bottomLeft->GetY() + : m_bottomRight->GetY()); +} diff --git a/xfa/fxbarcode/pdf417/BC_PDF417BoundingBox.h b/xfa/fxbarcode/pdf417/BC_PDF417BoundingBox.h new file mode 100644 index 0000000000..8b9563587d --- /dev/null +++ b/xfa/fxbarcode/pdf417/BC_PDF417BoundingBox.h @@ -0,0 +1,61 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef XFA_FXBARCODE_PDF417_BC_PDF417BOUNDINGBOX_H_ +#define XFA_FXBARCODE_PDF417_BC_PDF417BOUNDINGBOX_H_ + +#include "core/include/fxcrt/fx_system.h" + +class CBC_CommonBitMatrix; +class CBC_ResultPoint; + +class CBC_BoundingBox { + public: + CBC_BoundingBox(CBC_CommonBitMatrix* image, + CBC_ResultPoint* topLeft, + CBC_ResultPoint* bottomLeft, + CBC_ResultPoint* topRight, + CBC_ResultPoint* bottomRight, + int32_t& e); + CBC_BoundingBox(CBC_BoundingBox* boundingBox); + virtual ~CBC_BoundingBox(); + static CBC_BoundingBox* merge(CBC_BoundingBox* leftBox, + CBC_BoundingBox* rightBox, + int32_t& e); + CBC_BoundingBox* addMissingRows(int32_t missingStartRows, + int32_t missingEndRows, + FX_BOOL isLeft, + int32_t& e); + void setTopRight(CBC_ResultPoint topRight); + void setBottomRight(CBC_ResultPoint bottomRight); + int32_t getMinX(); + int32_t getMaxX(); + int32_t getMinY(); + int32_t getMaxY(); + CBC_ResultPoint* getTopLeft(); + CBC_ResultPoint* getTopRight(); + CBC_ResultPoint* getBottomLeft(); + CBC_ResultPoint* getBottomRight(); + + private: + CBC_CommonBitMatrix* m_image; + CBC_ResultPoint* m_topLeft; + CBC_ResultPoint* m_bottomLeft; + CBC_ResultPoint* m_topRight; + CBC_ResultPoint* m_bottomRight; + int32_t m_minX; + int32_t m_maxX; + int32_t m_minY; + int32_t m_maxY; + void init(CBC_CommonBitMatrix* image, + CBC_ResultPoint* topLeft, + CBC_ResultPoint* bottomLeft, + CBC_ResultPoint* topRight, + CBC_ResultPoint* bottomRight); + void calculateMinMaxValues(); +}; + +#endif // XFA_FXBARCODE_PDF417_BC_PDF417BOUNDINGBOX_H_ diff --git a/xfa/fxbarcode/pdf417/BC_PDF417Codeword.cpp b/xfa/fxbarcode/pdf417/BC_PDF417Codeword.cpp new file mode 100644 index 0000000000..0280ea0953 --- /dev/null +++ b/xfa/fxbarcode/pdf417/BC_PDF417Codeword.cpp @@ -0,0 +1,70 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com +// Original code is licensed as follows: +/* + * Copyright 2013 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "xfa/fxbarcode/pdf417/BC_PDF417Codeword.h" + +int32_t CBC_Codeword::BARCODE_ROW_UNKNOWN = -1; +CBC_Codeword::CBC_Codeword(int32_t startX, + int32_t endX, + int32_t bucket, + int32_t cvalue) { + m_startX = startX; + m_endX = endX; + m_bucket = bucket; + m_value = cvalue; + m_rowNumber = BARCODE_ROW_UNKNOWN; +} +CBC_Codeword::~CBC_Codeword() {} +FX_BOOL CBC_Codeword::hasValidRowNumber() { + return isValidRowNumber(m_rowNumber); +} +FX_BOOL CBC_Codeword::isValidRowNumber(int32_t rowNumber) { + return m_rowNumber != BARCODE_ROW_UNKNOWN && + m_bucket == (m_rowNumber % 3) * 3; +} +void CBC_Codeword::setRowNumberAsRowIndicatorColumn() { + m_rowNumber = (m_value / 30) * 3 + m_bucket / 3; +} +int32_t CBC_Codeword::getWidth() { + return m_endX - m_startX; +} +int32_t CBC_Codeword::getStartX() { + return m_startX; +} +int32_t CBC_Codeword::getEndX() { + return m_endX; +} +int32_t CBC_Codeword::getBucket() { + return m_bucket; +} +int32_t CBC_Codeword::getValue() { + return m_value; +} +int32_t CBC_Codeword::getRowNumber() { + return m_rowNumber; +} +void CBC_Codeword::setRowNumber(int32_t rowNumber) { + m_rowNumber = rowNumber; +} +CFX_ByteString CBC_Codeword::toString() { + return m_rowNumber + (FX_CHAR)'|' + m_value; +} diff --git a/xfa/fxbarcode/pdf417/BC_PDF417Codeword.h b/xfa/fxbarcode/pdf417/BC_PDF417Codeword.h new file mode 100644 index 0000000000..e1ca60f229 --- /dev/null +++ b/xfa/fxbarcode/pdf417/BC_PDF417Codeword.h @@ -0,0 +1,37 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef XFA_FXBARCODE_PDF417_BC_PDF417CODEWORD_H_ +#define XFA_FXBARCODE_PDF417_BC_PDF417CODEWORD_H_ + +#include "core/include/fxcrt/fx_basic.h" + +class CBC_Codeword { + public: + CBC_Codeword(int32_t startX, int32_t endX, int32_t bucket, int32_t value); + virtual ~CBC_Codeword(); + FX_BOOL hasValidRowNumber(); + FX_BOOL isValidRowNumber(int32_t rowNumber); + void setRowNumberAsRowIndicatorColumn(); + int32_t getWidth(); + int32_t getStartX(); + int32_t getEndX(); + int32_t getBucket(); + int32_t getValue(); + int32_t getRowNumber(); + void setRowNumber(int32_t rowNumber); + CFX_ByteString toString(); + + private: + static int32_t BARCODE_ROW_UNKNOWN; + int32_t m_startX; + int32_t m_endX; + int32_t m_bucket; + int32_t m_value; + int32_t m_rowNumber; +}; + +#endif // XFA_FXBARCODE_PDF417_BC_PDF417CODEWORD_H_ diff --git a/xfa/fxbarcode/pdf417/BC_PDF417CodewordDecoder.cpp b/xfa/fxbarcode/pdf417/BC_PDF417CodewordDecoder.cpp new file mode 100644 index 0000000000..dfbbc70264 --- /dev/null +++ b/xfa/fxbarcode/pdf417/BC_PDF417CodewordDecoder.cpp @@ -0,0 +1,117 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com +// Original code is licensed as follows: +/* + * Copyright 2013 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <limits> + +#include "xfa/fxbarcode/pdf417/BC_PDF417CodewordDecoder.h" +#include "xfa/fxbarcode/pdf417/BC_PDF417Common.h" + +#define SYMBOL_TABLE_Length 2787 + +FX_FLOAT CBC_PDF417CodewordDecoder::RATIOS_TABLE[2787][8] = {{0}}; + +CBC_PDF417CodewordDecoder::CBC_PDF417CodewordDecoder() {} +CBC_PDF417CodewordDecoder::~CBC_PDF417CodewordDecoder() {} +void CBC_PDF417CodewordDecoder::Initialize() { + for (int32_t i = 0; i < SYMBOL_TABLE_Length; i++) { + int32_t currentSymbol = CBC_PDF417Common::SYMBOL_TABLE[i]; + int32_t currentBit = currentSymbol & 0x1; + for (int32_t j = 0; j < CBC_PDF417Common::BARS_IN_MODULE; j++) { + FX_FLOAT size = 0.0f; + while ((currentSymbol & 0x1) == currentBit) { + size += 1.0f; + currentSymbol >>= 1; + } + currentBit = currentSymbol & 0x1; + RATIOS_TABLE[i][CBC_PDF417Common::BARS_IN_MODULE - j - 1] = + size / CBC_PDF417Common::MODULES_IN_CODEWORD; + } + } +} +void CBC_PDF417CodewordDecoder::Finalize() {} +int32_t CBC_PDF417CodewordDecoder::getDecodedValue( + CFX_Int32Array& moduleBitCount) { + CFX_Int32Array* array = sampleBitCounts(moduleBitCount); + int32_t decodedValue = getDecodedCodewordValue(*array); + delete array; + if (decodedValue != -1) { + return decodedValue; + } + return getClosestDecodedValue(moduleBitCount); +} +CFX_Int32Array* CBC_PDF417CodewordDecoder::sampleBitCounts( + CFX_Int32Array& moduleBitCount) { + FX_FLOAT bitCountSum = + (FX_FLOAT)CBC_PDF417Common::getBitCountSum(moduleBitCount); + CFX_Int32Array* bitCount = new CFX_Int32Array(); + bitCount->SetSize(CBC_PDF417Common::BARS_IN_MODULE); + int32_t bitCountIndex = 0; + int32_t sumPreviousBits = 0; + for (int32_t i = 0; i < CBC_PDF417Common::MODULES_IN_CODEWORD; i++) { + FX_FLOAT sampleIndex = + bitCountSum / (2 * CBC_PDF417Common::MODULES_IN_CODEWORD) + + (i * bitCountSum) / CBC_PDF417Common::MODULES_IN_CODEWORD; + if (sumPreviousBits + moduleBitCount.GetAt(bitCountIndex) <= sampleIndex) { + sumPreviousBits += moduleBitCount.GetAt(bitCountIndex); + bitCountIndex++; + } + bitCount->SetAt(bitCountIndex, bitCount->GetAt(bitCountIndex) + 1); + } + return bitCount; +} +int32_t CBC_PDF417CodewordDecoder::getDecodedCodewordValue( + CFX_Int32Array& moduleBitCount) { + int32_t decodedValue = getBitValue(moduleBitCount); + return CBC_PDF417Common::getCodeword(decodedValue) == -1 ? -1 : decodedValue; +} +int32_t CBC_PDF417CodewordDecoder::getBitValue(CFX_Int32Array& moduleBitCount) { + int64_t result = 0; + for (int32_t i = 0; i < moduleBitCount.GetSize(); i++) { + for (int32_t bit = 0; bit < moduleBitCount.GetAt(i); bit++) { + result = (result << 1) | (i % 2 == 0 ? 1 : 0); + } + } + return (int32_t)result; +} +int32_t CBC_PDF417CodewordDecoder::getClosestDecodedValue( + CFX_Int32Array& moduleBitCount) { + int32_t bitCountSum = CBC_PDF417Common::getBitCountSum(moduleBitCount); + CFX_FloatArray bitCountRatios; + bitCountRatios.SetSize(CBC_PDF417Common::BARS_IN_MODULE); + for (int32_t i = 0; i < bitCountRatios.GetSize(); i++) { + bitCountRatios[i] = moduleBitCount.GetAt(i) / (FX_FLOAT)bitCountSum; + } + FX_FLOAT bestMatchError = std::numeric_limits<int32_t>::max(); + int32_t bestMatch = -1; + for (int32_t j = 0; j < SYMBOL_TABLE_Length; j++) { + FX_FLOAT error = 0.0f; + for (int32_t k = 0; k < CBC_PDF417Common::BARS_IN_MODULE; k++) { + FX_FLOAT diff = RATIOS_TABLE[j][k] - bitCountRatios[k]; + error += diff * diff; + } + if (error < bestMatchError) { + bestMatchError = error; + bestMatch = CBC_PDF417Common::SYMBOL_TABLE[j]; + } + } + return bestMatch; +} diff --git a/xfa/fxbarcode/pdf417/BC_PDF417CodewordDecoder.h b/xfa/fxbarcode/pdf417/BC_PDF417CodewordDecoder.h new file mode 100644 index 0000000000..920409df84 --- /dev/null +++ b/xfa/fxbarcode/pdf417/BC_PDF417CodewordDecoder.h @@ -0,0 +1,28 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef XFA_FXBARCODE_PDF417_BC_PDF417CODEWORDDECODER_H_ +#define XFA_FXBARCODE_PDF417_BC_PDF417CODEWORDDECODER_H_ + +#include "core/include/fxcrt/fx_basic.h" + +class CBC_PDF417CodewordDecoder { + public: + CBC_PDF417CodewordDecoder(); + virtual ~CBC_PDF417CodewordDecoder(); + static void Initialize(); + static void Finalize(); + static int32_t getDecodedValue(CFX_Int32Array& moduleBitCount); + + private: + static FX_FLOAT RATIOS_TABLE[][8]; + static CFX_Int32Array* sampleBitCounts(CFX_Int32Array& moduleBitCount); + static int32_t getDecodedCodewordValue(CFX_Int32Array& moduleBitCount); + static int32_t getBitValue(CFX_Int32Array& moduleBitCount); + static int32_t getClosestDecodedValue(CFX_Int32Array& moduleBitCount); +}; + +#endif // XFA_FXBARCODE_PDF417_BC_PDF417CODEWORDDECODER_H_ diff --git a/xfa/fxbarcode/pdf417/BC_PDF417Common.cpp b/xfa/fxbarcode/pdf417/BC_PDF417Common.cpp new file mode 100644 index 0000000000..fa4647db84 --- /dev/null +++ b/xfa/fxbarcode/pdf417/BC_PDF417Common.cpp @@ -0,0 +1,651 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com +// Original code is licensed as follows: +/* + * Copyright 2009 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "xfa/fxbarcode/pdf417/BC_PDF417Common.h" + +int32_t CBC_PDF417Common::NUMBER_OF_CODEWORDS = 929; +int32_t CBC_PDF417Common::MAX_CODEWORDS_IN_BARCODE = NUMBER_OF_CODEWORDS - 1; +int32_t CBC_PDF417Common::MIN_ROWS_IN_BARCODE = 3; +int32_t CBC_PDF417Common::MAX_ROWS_IN_BARCODE = 90; +int32_t CBC_PDF417Common::MAX_CODEWORDS_IN_ROW = 32; +int32_t CBC_PDF417Common::MODULES_IN_CODEWORD = 17; +int32_t CBC_PDF417Common::MODULES_IN_STOP_PATTERN = 18; +int32_t CBC_PDF417Common::BARS_IN_MODULE = 8; +CFX_Int32Array* CBC_PDF417Common::EMPTY_INT_ARRAY = NULL; +int32_t CBC_PDF417Common::SYMBOL_TABLE[] = { + 0x1025e, 0x1027a, 0x1029e, 0x102bc, 0x102f2, 0x102f4, 0x1032e, 0x1034e, + 0x1035c, 0x10396, 0x103a6, 0x103ac, 0x10422, 0x10428, 0x10436, 0x10442, + 0x10444, 0x10448, 0x10450, 0x1045e, 0x10466, 0x1046c, 0x1047a, 0x10482, + 0x1049e, 0x104a0, 0x104bc, 0x104c6, 0x104d8, 0x104ee, 0x104f2, 0x104f4, + 0x10504, 0x10508, 0x10510, 0x1051e, 0x10520, 0x1053c, 0x10540, 0x10578, + 0x10586, 0x1058c, 0x10598, 0x105b0, 0x105be, 0x105ce, 0x105dc, 0x105e2, + 0x105e4, 0x105e8, 0x105f6, 0x1062e, 0x1064e, 0x1065c, 0x1068e, 0x1069c, + 0x106b8, 0x106de, 0x106fa, 0x10716, 0x10726, 0x1072c, 0x10746, 0x1074c, + 0x10758, 0x1076e, 0x10792, 0x10794, 0x107a2, 0x107a4, 0x107a8, 0x107b6, + 0x10822, 0x10828, 0x10842, 0x10848, 0x10850, 0x1085e, 0x10866, 0x1086c, + 0x1087a, 0x10882, 0x10884, 0x10890, 0x1089e, 0x108a0, 0x108bc, 0x108c6, + 0x108cc, 0x108d8, 0x108ee, 0x108f2, 0x108f4, 0x10902, 0x10908, 0x1091e, + 0x10920, 0x1093c, 0x10940, 0x10978, 0x10986, 0x10998, 0x109b0, 0x109be, + 0x109ce, 0x109dc, 0x109e2, 0x109e4, 0x109e8, 0x109f6, 0x10a08, 0x10a10, + 0x10a1e, 0x10a20, 0x10a3c, 0x10a40, 0x10a78, 0x10af0, 0x10b06, 0x10b0c, + 0x10b18, 0x10b30, 0x10b3e, 0x10b60, 0x10b7c, 0x10b8e, 0x10b9c, 0x10bb8, + 0x10bc2, 0x10bc4, 0x10bc8, 0x10bd0, 0x10bde, 0x10be6, 0x10bec, 0x10c2e, + 0x10c4e, 0x10c5c, 0x10c62, 0x10c64, 0x10c68, 0x10c76, 0x10c8e, 0x10c9c, + 0x10cb8, 0x10cc2, 0x10cc4, 0x10cc8, 0x10cd0, 0x10cde, 0x10ce6, 0x10cec, + 0x10cfa, 0x10d0e, 0x10d1c, 0x10d38, 0x10d70, 0x10d7e, 0x10d82, 0x10d84, + 0x10d88, 0x10d90, 0x10d9e, 0x10da0, 0x10dbc, 0x10dc6, 0x10dcc, 0x10dd8, + 0x10dee, 0x10df2, 0x10df4, 0x10e16, 0x10e26, 0x10e2c, 0x10e46, 0x10e58, + 0x10e6e, 0x10e86, 0x10e8c, 0x10e98, 0x10eb0, 0x10ebe, 0x10ece, 0x10edc, + 0x10f0a, 0x10f12, 0x10f14, 0x10f22, 0x10f28, 0x10f36, 0x10f42, 0x10f44, + 0x10f48, 0x10f50, 0x10f5e, 0x10f66, 0x10f6c, 0x10fb2, 0x10fb4, 0x11022, + 0x11028, 0x11042, 0x11048, 0x11050, 0x1105e, 0x1107a, 0x11082, 0x11084, + 0x11090, 0x1109e, 0x110a0, 0x110bc, 0x110c6, 0x110cc, 0x110d8, 0x110ee, + 0x110f2, 0x110f4, 0x11102, 0x1111e, 0x11120, 0x1113c, 0x11140, 0x11178, + 0x11186, 0x11198, 0x111b0, 0x111be, 0x111ce, 0x111dc, 0x111e2, 0x111e4, + 0x111e8, 0x111f6, 0x11208, 0x1121e, 0x11220, 0x11278, 0x112f0, 0x1130c, + 0x11330, 0x1133e, 0x11360, 0x1137c, 0x1138e, 0x1139c, 0x113b8, 0x113c2, + 0x113c8, 0x113d0, 0x113de, 0x113e6, 0x113ec, 0x11408, 0x11410, 0x1141e, + 0x11420, 0x1143c, 0x11440, 0x11478, 0x114f0, 0x115e0, 0x1160c, 0x11618, + 0x11630, 0x1163e, 0x11660, 0x1167c, 0x116c0, 0x116f8, 0x1171c, 0x11738, + 0x11770, 0x1177e, 0x11782, 0x11784, 0x11788, 0x11790, 0x1179e, 0x117a0, + 0x117bc, 0x117c6, 0x117cc, 0x117d8, 0x117ee, 0x1182e, 0x11834, 0x1184e, + 0x1185c, 0x11862, 0x11864, 0x11868, 0x11876, 0x1188e, 0x1189c, 0x118b8, + 0x118c2, 0x118c8, 0x118d0, 0x118de, 0x118e6, 0x118ec, 0x118fa, 0x1190e, + 0x1191c, 0x11938, 0x11970, 0x1197e, 0x11982, 0x11984, 0x11990, 0x1199e, + 0x119a0, 0x119bc, 0x119c6, 0x119cc, 0x119d8, 0x119ee, 0x119f2, 0x119f4, + 0x11a0e, 0x11a1c, 0x11a38, 0x11a70, 0x11a7e, 0x11ae0, 0x11afc, 0x11b08, + 0x11b10, 0x11b1e, 0x11b20, 0x11b3c, 0x11b40, 0x11b78, 0x11b8c, 0x11b98, + 0x11bb0, 0x11bbe, 0x11bce, 0x11bdc, 0x11be2, 0x11be4, 0x11be8, 0x11bf6, + 0x11c16, 0x11c26, 0x11c2c, 0x11c46, 0x11c4c, 0x11c58, 0x11c6e, 0x11c86, + 0x11c98, 0x11cb0, 0x11cbe, 0x11cce, 0x11cdc, 0x11ce2, 0x11ce4, 0x11ce8, + 0x11cf6, 0x11d06, 0x11d0c, 0x11d18, 0x11d30, 0x11d3e, 0x11d60, 0x11d7c, + 0x11d8e, 0x11d9c, 0x11db8, 0x11dc4, 0x11dc8, 0x11dd0, 0x11dde, 0x11de6, + 0x11dec, 0x11dfa, 0x11e0a, 0x11e12, 0x11e14, 0x11e22, 0x11e24, 0x11e28, + 0x11e36, 0x11e42, 0x11e44, 0x11e50, 0x11e5e, 0x11e66, 0x11e6c, 0x11e82, + 0x11e84, 0x11e88, 0x11e90, 0x11e9e, 0x11ea0, 0x11ebc, 0x11ec6, 0x11ecc, + 0x11ed8, 0x11eee, 0x11f1a, 0x11f2e, 0x11f32, 0x11f34, 0x11f4e, 0x11f5c, + 0x11f62, 0x11f64, 0x11f68, 0x11f76, 0x12048, 0x1205e, 0x12082, 0x12084, + 0x12090, 0x1209e, 0x120a0, 0x120bc, 0x120d8, 0x120f2, 0x120f4, 0x12108, + 0x1211e, 0x12120, 0x1213c, 0x12140, 0x12178, 0x12186, 0x12198, 0x121b0, + 0x121be, 0x121e2, 0x121e4, 0x121e8, 0x121f6, 0x12204, 0x12210, 0x1221e, + 0x12220, 0x12278, 0x122f0, 0x12306, 0x1230c, 0x12330, 0x1233e, 0x12360, + 0x1237c, 0x1238e, 0x1239c, 0x123b8, 0x123c2, 0x123c8, 0x123d0, 0x123e6, + 0x123ec, 0x1241e, 0x12420, 0x1243c, 0x124f0, 0x125e0, 0x12618, 0x1263e, + 0x12660, 0x1267c, 0x126c0, 0x126f8, 0x12738, 0x12770, 0x1277e, 0x12782, + 0x12784, 0x12790, 0x1279e, 0x127a0, 0x127bc, 0x127c6, 0x127cc, 0x127d8, + 0x127ee, 0x12820, 0x1283c, 0x12840, 0x12878, 0x128f0, 0x129e0, 0x12bc0, + 0x12c18, 0x12c30, 0x12c3e, 0x12c60, 0x12c7c, 0x12cc0, 0x12cf8, 0x12df0, + 0x12e1c, 0x12e38, 0x12e70, 0x12e7e, 0x12ee0, 0x12efc, 0x12f04, 0x12f08, + 0x12f10, 0x12f20, 0x12f3c, 0x12f40, 0x12f78, 0x12f86, 0x12f8c, 0x12f98, + 0x12fb0, 0x12fbe, 0x12fce, 0x12fdc, 0x1302e, 0x1304e, 0x1305c, 0x13062, + 0x13068, 0x1308e, 0x1309c, 0x130b8, 0x130c2, 0x130c8, 0x130d0, 0x130de, + 0x130ec, 0x130fa, 0x1310e, 0x13138, 0x13170, 0x1317e, 0x13182, 0x13184, + 0x13190, 0x1319e, 0x131a0, 0x131bc, 0x131c6, 0x131cc, 0x131d8, 0x131f2, + 0x131f4, 0x1320e, 0x1321c, 0x13270, 0x1327e, 0x132e0, 0x132fc, 0x13308, + 0x1331e, 0x13320, 0x1333c, 0x13340, 0x13378, 0x13386, 0x13398, 0x133b0, + 0x133be, 0x133ce, 0x133dc, 0x133e2, 0x133e4, 0x133e8, 0x133f6, 0x1340e, + 0x1341c, 0x13438, 0x13470, 0x1347e, 0x134e0, 0x134fc, 0x135c0, 0x135f8, + 0x13608, 0x13610, 0x1361e, 0x13620, 0x1363c, 0x13640, 0x13678, 0x136f0, + 0x1370c, 0x13718, 0x13730, 0x1373e, 0x13760, 0x1377c, 0x1379c, 0x137b8, + 0x137c2, 0x137c4, 0x137c8, 0x137d0, 0x137de, 0x137e6, 0x137ec, 0x13816, + 0x13826, 0x1382c, 0x13846, 0x1384c, 0x13858, 0x1386e, 0x13874, 0x13886, + 0x13898, 0x138b0, 0x138be, 0x138ce, 0x138dc, 0x138e2, 0x138e4, 0x138e8, + 0x13906, 0x1390c, 0x13930, 0x1393e, 0x13960, 0x1397c, 0x1398e, 0x1399c, + 0x139b8, 0x139c8, 0x139d0, 0x139de, 0x139e6, 0x139ec, 0x139fa, 0x13a06, + 0x13a0c, 0x13a18, 0x13a30, 0x13a3e, 0x13a60, 0x13a7c, 0x13ac0, 0x13af8, + 0x13b0e, 0x13b1c, 0x13b38, 0x13b70, 0x13b7e, 0x13b88, 0x13b90, 0x13b9e, + 0x13ba0, 0x13bbc, 0x13bcc, 0x13bd8, 0x13bee, 0x13bf2, 0x13bf4, 0x13c12, + 0x13c14, 0x13c22, 0x13c24, 0x13c28, 0x13c36, 0x13c42, 0x13c48, 0x13c50, + 0x13c5e, 0x13c66, 0x13c6c, 0x13c82, 0x13c84, 0x13c90, 0x13c9e, 0x13ca0, + 0x13cbc, 0x13cc6, 0x13ccc, 0x13cd8, 0x13cee, 0x13d02, 0x13d04, 0x13d08, + 0x13d10, 0x13d1e, 0x13d20, 0x13d3c, 0x13d40, 0x13d78, 0x13d86, 0x13d8c, + 0x13d98, 0x13db0, 0x13dbe, 0x13dce, 0x13ddc, 0x13de4, 0x13de8, 0x13df6, + 0x13e1a, 0x13e2e, 0x13e32, 0x13e34, 0x13e4e, 0x13e5c, 0x13e62, 0x13e64, + 0x13e68, 0x13e76, 0x13e8e, 0x13e9c, 0x13eb8, 0x13ec2, 0x13ec4, 0x13ec8, + 0x13ed0, 0x13ede, 0x13ee6, 0x13eec, 0x13f26, 0x13f2c, 0x13f3a, 0x13f46, + 0x13f4c, 0x13f58, 0x13f6e, 0x13f72, 0x13f74, 0x14082, 0x1409e, 0x140a0, + 0x140bc, 0x14104, 0x14108, 0x14110, 0x1411e, 0x14120, 0x1413c, 0x14140, + 0x14178, 0x1418c, 0x14198, 0x141b0, 0x141be, 0x141e2, 0x141e4, 0x141e8, + 0x14208, 0x14210, 0x1421e, 0x14220, 0x1423c, 0x14240, 0x14278, 0x142f0, + 0x14306, 0x1430c, 0x14318, 0x14330, 0x1433e, 0x14360, 0x1437c, 0x1438e, + 0x143c2, 0x143c4, 0x143c8, 0x143d0, 0x143e6, 0x143ec, 0x14408, 0x14410, + 0x1441e, 0x14420, 0x1443c, 0x14440, 0x14478, 0x144f0, 0x145e0, 0x1460c, + 0x14618, 0x14630, 0x1463e, 0x14660, 0x1467c, 0x146c0, 0x146f8, 0x1471c, + 0x14738, 0x14770, 0x1477e, 0x14782, 0x14784, 0x14788, 0x14790, 0x147a0, + 0x147bc, 0x147c6, 0x147cc, 0x147d8, 0x147ee, 0x14810, 0x14820, 0x1483c, + 0x14840, 0x14878, 0x148f0, 0x149e0, 0x14bc0, 0x14c30, 0x14c3e, 0x14c60, + 0x14c7c, 0x14cc0, 0x14cf8, 0x14df0, 0x14e38, 0x14e70, 0x14e7e, 0x14ee0, + 0x14efc, 0x14f04, 0x14f08, 0x14f10, 0x14f1e, 0x14f20, 0x14f3c, 0x14f40, + 0x14f78, 0x14f86, 0x14f8c, 0x14f98, 0x14fb0, 0x14fce, 0x14fdc, 0x15020, + 0x15040, 0x15078, 0x150f0, 0x151e0, 0x153c0, 0x15860, 0x1587c, 0x158c0, + 0x158f8, 0x159f0, 0x15be0, 0x15c70, 0x15c7e, 0x15ce0, 0x15cfc, 0x15dc0, + 0x15df8, 0x15e08, 0x15e10, 0x15e20, 0x15e40, 0x15e78, 0x15ef0, 0x15f0c, + 0x15f18, 0x15f30, 0x15f60, 0x15f7c, 0x15f8e, 0x15f9c, 0x15fb8, 0x1604e, + 0x1605c, 0x1608e, 0x1609c, 0x160b8, 0x160c2, 0x160c4, 0x160c8, 0x160de, + 0x1610e, 0x1611c, 0x16138, 0x16170, 0x1617e, 0x16184, 0x16188, 0x16190, + 0x1619e, 0x161a0, 0x161bc, 0x161c6, 0x161cc, 0x161d8, 0x161f2, 0x161f4, + 0x1620e, 0x1621c, 0x16238, 0x16270, 0x1627e, 0x162e0, 0x162fc, 0x16304, + 0x16308, 0x16310, 0x1631e, 0x16320, 0x1633c, 0x16340, 0x16378, 0x16386, + 0x1638c, 0x16398, 0x163b0, 0x163be, 0x163ce, 0x163dc, 0x163e2, 0x163e4, + 0x163e8, 0x163f6, 0x1640e, 0x1641c, 0x16438, 0x16470, 0x1647e, 0x164e0, + 0x164fc, 0x165c0, 0x165f8, 0x16610, 0x1661e, 0x16620, 0x1663c, 0x16640, + 0x16678, 0x166f0, 0x16718, 0x16730, 0x1673e, 0x16760, 0x1677c, 0x1678e, + 0x1679c, 0x167b8, 0x167c2, 0x167c4, 0x167c8, 0x167d0, 0x167de, 0x167e6, + 0x167ec, 0x1681c, 0x16838, 0x16870, 0x168e0, 0x168fc, 0x169c0, 0x169f8, + 0x16bf0, 0x16c10, 0x16c1e, 0x16c20, 0x16c3c, 0x16c40, 0x16c78, 0x16cf0, + 0x16de0, 0x16e18, 0x16e30, 0x16e3e, 0x16e60, 0x16e7c, 0x16ec0, 0x16ef8, + 0x16f1c, 0x16f38, 0x16f70, 0x16f7e, 0x16f84, 0x16f88, 0x16f90, 0x16f9e, + 0x16fa0, 0x16fbc, 0x16fc6, 0x16fcc, 0x16fd8, 0x17026, 0x1702c, 0x17046, + 0x1704c, 0x17058, 0x1706e, 0x17086, 0x1708c, 0x17098, 0x170b0, 0x170be, + 0x170ce, 0x170dc, 0x170e8, 0x17106, 0x1710c, 0x17118, 0x17130, 0x1713e, + 0x17160, 0x1717c, 0x1718e, 0x1719c, 0x171b8, 0x171c2, 0x171c4, 0x171c8, + 0x171d0, 0x171de, 0x171e6, 0x171ec, 0x171fa, 0x17206, 0x1720c, 0x17218, + 0x17230, 0x1723e, 0x17260, 0x1727c, 0x172c0, 0x172f8, 0x1730e, 0x1731c, + 0x17338, 0x17370, 0x1737e, 0x17388, 0x17390, 0x1739e, 0x173a0, 0x173bc, + 0x173cc, 0x173d8, 0x173ee, 0x173f2, 0x173f4, 0x1740c, 0x17418, 0x17430, + 0x1743e, 0x17460, 0x1747c, 0x174c0, 0x174f8, 0x175f0, 0x1760e, 0x1761c, + 0x17638, 0x17670, 0x1767e, 0x176e0, 0x176fc, 0x17708, 0x17710, 0x1771e, + 0x17720, 0x1773c, 0x17740, 0x17778, 0x17798, 0x177b0, 0x177be, 0x177dc, + 0x177e2, 0x177e4, 0x177e8, 0x17822, 0x17824, 0x17828, 0x17836, 0x17842, + 0x17844, 0x17848, 0x17850, 0x1785e, 0x17866, 0x1786c, 0x17882, 0x17884, + 0x17888, 0x17890, 0x1789e, 0x178a0, 0x178bc, 0x178c6, 0x178cc, 0x178d8, + 0x178ee, 0x178f2, 0x178f4, 0x17902, 0x17904, 0x17908, 0x17910, 0x1791e, + 0x17920, 0x1793c, 0x17940, 0x17978, 0x17986, 0x1798c, 0x17998, 0x179b0, + 0x179be, 0x179ce, 0x179dc, 0x179e2, 0x179e4, 0x179e8, 0x179f6, 0x17a04, + 0x17a08, 0x17a10, 0x17a1e, 0x17a20, 0x17a3c, 0x17a40, 0x17a78, 0x17af0, + 0x17b06, 0x17b0c, 0x17b18, 0x17b30, 0x17b3e, 0x17b60, 0x17b7c, 0x17b8e, + 0x17b9c, 0x17bb8, 0x17bc4, 0x17bc8, 0x17bd0, 0x17bde, 0x17be6, 0x17bec, + 0x17c2e, 0x17c32, 0x17c34, 0x17c4e, 0x17c5c, 0x17c62, 0x17c64, 0x17c68, + 0x17c76, 0x17c8e, 0x17c9c, 0x17cb8, 0x17cc2, 0x17cc4, 0x17cc8, 0x17cd0, + 0x17cde, 0x17ce6, 0x17cec, 0x17d0e, 0x17d1c, 0x17d38, 0x17d70, 0x17d82, + 0x17d84, 0x17d88, 0x17d90, 0x17d9e, 0x17da0, 0x17dbc, 0x17dc6, 0x17dcc, + 0x17dd8, 0x17dee, 0x17e26, 0x17e2c, 0x17e3a, 0x17e46, 0x17e4c, 0x17e58, + 0x17e6e, 0x17e72, 0x17e74, 0x17e86, 0x17e8c, 0x17e98, 0x17eb0, 0x17ece, + 0x17edc, 0x17ee2, 0x17ee4, 0x17ee8, 0x17ef6, 0x1813a, 0x18172, 0x18174, + 0x18216, 0x18226, 0x1823a, 0x1824c, 0x18258, 0x1826e, 0x18272, 0x18274, + 0x18298, 0x182be, 0x182e2, 0x182e4, 0x182e8, 0x182f6, 0x1835e, 0x1837a, + 0x183ae, 0x183d6, 0x18416, 0x18426, 0x1842c, 0x1843a, 0x18446, 0x18458, + 0x1846e, 0x18472, 0x18474, 0x18486, 0x184b0, 0x184be, 0x184ce, 0x184dc, + 0x184e2, 0x184e4, 0x184e8, 0x184f6, 0x18506, 0x1850c, 0x18518, 0x18530, + 0x1853e, 0x18560, 0x1857c, 0x1858e, 0x1859c, 0x185b8, 0x185c2, 0x185c4, + 0x185c8, 0x185d0, 0x185de, 0x185e6, 0x185ec, 0x185fa, 0x18612, 0x18614, + 0x18622, 0x18628, 0x18636, 0x18642, 0x18650, 0x1865e, 0x1867a, 0x18682, + 0x18684, 0x18688, 0x18690, 0x1869e, 0x186a0, 0x186bc, 0x186c6, 0x186cc, + 0x186d8, 0x186ee, 0x186f2, 0x186f4, 0x1872e, 0x1874e, 0x1875c, 0x18796, + 0x187a6, 0x187ac, 0x187d2, 0x187d4, 0x18826, 0x1882c, 0x1883a, 0x18846, + 0x1884c, 0x18858, 0x1886e, 0x18872, 0x18874, 0x18886, 0x18898, 0x188b0, + 0x188be, 0x188ce, 0x188dc, 0x188e2, 0x188e4, 0x188e8, 0x188f6, 0x1890c, + 0x18930, 0x1893e, 0x18960, 0x1897c, 0x1898e, 0x189b8, 0x189c2, 0x189c8, + 0x189d0, 0x189de, 0x189e6, 0x189ec, 0x189fa, 0x18a18, 0x18a30, 0x18a3e, + 0x18a60, 0x18a7c, 0x18ac0, 0x18af8, 0x18b1c, 0x18b38, 0x18b70, 0x18b7e, + 0x18b82, 0x18b84, 0x18b88, 0x18b90, 0x18b9e, 0x18ba0, 0x18bbc, 0x18bc6, + 0x18bcc, 0x18bd8, 0x18bee, 0x18bf2, 0x18bf4, 0x18c22, 0x18c24, 0x18c28, + 0x18c36, 0x18c42, 0x18c48, 0x18c50, 0x18c5e, 0x18c66, 0x18c7a, 0x18c82, + 0x18c84, 0x18c90, 0x18c9e, 0x18ca0, 0x18cbc, 0x18ccc, 0x18cf2, 0x18cf4, + 0x18d04, 0x18d08, 0x18d10, 0x18d1e, 0x18d20, 0x18d3c, 0x18d40, 0x18d78, + 0x18d86, 0x18d98, 0x18dce, 0x18de2, 0x18de4, 0x18de8, 0x18e2e, 0x18e32, + 0x18e34, 0x18e4e, 0x18e5c, 0x18e62, 0x18e64, 0x18e68, 0x18e8e, 0x18e9c, + 0x18eb8, 0x18ec2, 0x18ec4, 0x18ec8, 0x18ed0, 0x18efa, 0x18f16, 0x18f26, + 0x18f2c, 0x18f46, 0x18f4c, 0x18f58, 0x18f6e, 0x18f8a, 0x18f92, 0x18f94, + 0x18fa2, 0x18fa4, 0x18fa8, 0x18fb6, 0x1902c, 0x1903a, 0x19046, 0x1904c, + 0x19058, 0x19072, 0x19074, 0x19086, 0x19098, 0x190b0, 0x190be, 0x190ce, + 0x190dc, 0x190e2, 0x190e8, 0x190f6, 0x19106, 0x1910c, 0x19130, 0x1913e, + 0x19160, 0x1917c, 0x1918e, 0x1919c, 0x191b8, 0x191c2, 0x191c8, 0x191d0, + 0x191de, 0x191e6, 0x191ec, 0x191fa, 0x19218, 0x1923e, 0x19260, 0x1927c, + 0x192c0, 0x192f8, 0x19338, 0x19370, 0x1937e, 0x19382, 0x19384, 0x19390, + 0x1939e, 0x193a0, 0x193bc, 0x193c6, 0x193cc, 0x193d8, 0x193ee, 0x193f2, + 0x193f4, 0x19430, 0x1943e, 0x19460, 0x1947c, 0x194c0, 0x194f8, 0x195f0, + 0x19638, 0x19670, 0x1967e, 0x196e0, 0x196fc, 0x19702, 0x19704, 0x19708, + 0x19710, 0x19720, 0x1973c, 0x19740, 0x19778, 0x19786, 0x1978c, 0x19798, + 0x197b0, 0x197be, 0x197ce, 0x197dc, 0x197e2, 0x197e4, 0x197e8, 0x19822, + 0x19824, 0x19842, 0x19848, 0x19850, 0x1985e, 0x19866, 0x1987a, 0x19882, + 0x19884, 0x19890, 0x1989e, 0x198a0, 0x198bc, 0x198cc, 0x198f2, 0x198f4, + 0x19902, 0x19908, 0x1991e, 0x19920, 0x1993c, 0x19940, 0x19978, 0x19986, + 0x19998, 0x199ce, 0x199e2, 0x199e4, 0x199e8, 0x19a08, 0x19a10, 0x19a1e, + 0x19a20, 0x19a3c, 0x19a40, 0x19a78, 0x19af0, 0x19b18, 0x19b3e, 0x19b60, + 0x19b9c, 0x19bc2, 0x19bc4, 0x19bc8, 0x19bd0, 0x19be6, 0x19c2e, 0x19c34, + 0x19c4e, 0x19c5c, 0x19c62, 0x19c64, 0x19c68, 0x19c8e, 0x19c9c, 0x19cb8, + 0x19cc2, 0x19cc8, 0x19cd0, 0x19ce6, 0x19cfa, 0x19d0e, 0x19d1c, 0x19d38, + 0x19d70, 0x19d7e, 0x19d82, 0x19d84, 0x19d88, 0x19d90, 0x19da0, 0x19dcc, + 0x19df2, 0x19df4, 0x19e16, 0x19e26, 0x19e2c, 0x19e46, 0x19e4c, 0x19e58, + 0x19e74, 0x19e86, 0x19e8c, 0x19e98, 0x19eb0, 0x19ebe, 0x19ece, 0x19ee2, + 0x19ee4, 0x19ee8, 0x19f0a, 0x19f12, 0x19f14, 0x19f22, 0x19f24, 0x19f28, + 0x19f42, 0x19f44, 0x19f48, 0x19f50, 0x19f5e, 0x19f6c, 0x19f9a, 0x19fae, + 0x19fb2, 0x19fb4, 0x1a046, 0x1a04c, 0x1a072, 0x1a074, 0x1a086, 0x1a08c, + 0x1a098, 0x1a0b0, 0x1a0be, 0x1a0e2, 0x1a0e4, 0x1a0e8, 0x1a0f6, 0x1a106, + 0x1a10c, 0x1a118, 0x1a130, 0x1a13e, 0x1a160, 0x1a17c, 0x1a18e, 0x1a19c, + 0x1a1b8, 0x1a1c2, 0x1a1c4, 0x1a1c8, 0x1a1d0, 0x1a1de, 0x1a1e6, 0x1a1ec, + 0x1a218, 0x1a230, 0x1a23e, 0x1a260, 0x1a27c, 0x1a2c0, 0x1a2f8, 0x1a31c, + 0x1a338, 0x1a370, 0x1a37e, 0x1a382, 0x1a384, 0x1a388, 0x1a390, 0x1a39e, + 0x1a3a0, 0x1a3bc, 0x1a3c6, 0x1a3cc, 0x1a3d8, 0x1a3ee, 0x1a3f2, 0x1a3f4, + 0x1a418, 0x1a430, 0x1a43e, 0x1a460, 0x1a47c, 0x1a4c0, 0x1a4f8, 0x1a5f0, + 0x1a61c, 0x1a638, 0x1a670, 0x1a67e, 0x1a6e0, 0x1a6fc, 0x1a702, 0x1a704, + 0x1a708, 0x1a710, 0x1a71e, 0x1a720, 0x1a73c, 0x1a740, 0x1a778, 0x1a786, + 0x1a78c, 0x1a798, 0x1a7b0, 0x1a7be, 0x1a7ce, 0x1a7dc, 0x1a7e2, 0x1a7e4, + 0x1a7e8, 0x1a830, 0x1a860, 0x1a87c, 0x1a8c0, 0x1a8f8, 0x1a9f0, 0x1abe0, + 0x1ac70, 0x1ac7e, 0x1ace0, 0x1acfc, 0x1adc0, 0x1adf8, 0x1ae04, 0x1ae08, + 0x1ae10, 0x1ae20, 0x1ae3c, 0x1ae40, 0x1ae78, 0x1aef0, 0x1af06, 0x1af0c, + 0x1af18, 0x1af30, 0x1af3e, 0x1af60, 0x1af7c, 0x1af8e, 0x1af9c, 0x1afb8, + 0x1afc4, 0x1afc8, 0x1afd0, 0x1afde, 0x1b042, 0x1b05e, 0x1b07a, 0x1b082, + 0x1b084, 0x1b088, 0x1b090, 0x1b09e, 0x1b0a0, 0x1b0bc, 0x1b0cc, 0x1b0f2, + 0x1b0f4, 0x1b102, 0x1b104, 0x1b108, 0x1b110, 0x1b11e, 0x1b120, 0x1b13c, + 0x1b140, 0x1b178, 0x1b186, 0x1b198, 0x1b1ce, 0x1b1e2, 0x1b1e4, 0x1b1e8, + 0x1b204, 0x1b208, 0x1b210, 0x1b21e, 0x1b220, 0x1b23c, 0x1b240, 0x1b278, + 0x1b2f0, 0x1b30c, 0x1b33e, 0x1b360, 0x1b39c, 0x1b3c2, 0x1b3c4, 0x1b3c8, + 0x1b3d0, 0x1b3e6, 0x1b410, 0x1b41e, 0x1b420, 0x1b43c, 0x1b440, 0x1b478, + 0x1b4f0, 0x1b5e0, 0x1b618, 0x1b660, 0x1b67c, 0x1b6c0, 0x1b738, 0x1b782, + 0x1b784, 0x1b788, 0x1b790, 0x1b79e, 0x1b7a0, 0x1b7cc, 0x1b82e, 0x1b84e, + 0x1b85c, 0x1b88e, 0x1b89c, 0x1b8b8, 0x1b8c2, 0x1b8c4, 0x1b8c8, 0x1b8d0, + 0x1b8e6, 0x1b8fa, 0x1b90e, 0x1b91c, 0x1b938, 0x1b970, 0x1b97e, 0x1b982, + 0x1b984, 0x1b988, 0x1b990, 0x1b99e, 0x1b9a0, 0x1b9cc, 0x1b9f2, 0x1b9f4, + 0x1ba0e, 0x1ba1c, 0x1ba38, 0x1ba70, 0x1ba7e, 0x1bae0, 0x1bafc, 0x1bb08, + 0x1bb10, 0x1bb20, 0x1bb3c, 0x1bb40, 0x1bb98, 0x1bbce, 0x1bbe2, 0x1bbe4, + 0x1bbe8, 0x1bc16, 0x1bc26, 0x1bc2c, 0x1bc46, 0x1bc4c, 0x1bc58, 0x1bc72, + 0x1bc74, 0x1bc86, 0x1bc8c, 0x1bc98, 0x1bcb0, 0x1bcbe, 0x1bcce, 0x1bce2, + 0x1bce4, 0x1bce8, 0x1bd06, 0x1bd0c, 0x1bd18, 0x1bd30, 0x1bd3e, 0x1bd60, + 0x1bd7c, 0x1bd9c, 0x1bdc2, 0x1bdc4, 0x1bdc8, 0x1bdd0, 0x1bde6, 0x1bdfa, + 0x1be12, 0x1be14, 0x1be22, 0x1be24, 0x1be28, 0x1be42, 0x1be44, 0x1be48, + 0x1be50, 0x1be5e, 0x1be66, 0x1be82, 0x1be84, 0x1be88, 0x1be90, 0x1be9e, + 0x1bea0, 0x1bebc, 0x1becc, 0x1bef4, 0x1bf1a, 0x1bf2e, 0x1bf32, 0x1bf34, + 0x1bf4e, 0x1bf5c, 0x1bf62, 0x1bf64, 0x1bf68, 0x1c09a, 0x1c0b2, 0x1c0b4, + 0x1c11a, 0x1c132, 0x1c134, 0x1c162, 0x1c164, 0x1c168, 0x1c176, 0x1c1ba, + 0x1c21a, 0x1c232, 0x1c234, 0x1c24e, 0x1c25c, 0x1c262, 0x1c264, 0x1c268, + 0x1c276, 0x1c28e, 0x1c2c2, 0x1c2c4, 0x1c2c8, 0x1c2d0, 0x1c2de, 0x1c2e6, + 0x1c2ec, 0x1c2fa, 0x1c316, 0x1c326, 0x1c33a, 0x1c346, 0x1c34c, 0x1c372, + 0x1c374, 0x1c41a, 0x1c42e, 0x1c432, 0x1c434, 0x1c44e, 0x1c45c, 0x1c462, + 0x1c464, 0x1c468, 0x1c476, 0x1c48e, 0x1c49c, 0x1c4b8, 0x1c4c2, 0x1c4c8, + 0x1c4d0, 0x1c4de, 0x1c4e6, 0x1c4ec, 0x1c4fa, 0x1c51c, 0x1c538, 0x1c570, + 0x1c57e, 0x1c582, 0x1c584, 0x1c588, 0x1c590, 0x1c59e, 0x1c5a0, 0x1c5bc, + 0x1c5c6, 0x1c5cc, 0x1c5d8, 0x1c5ee, 0x1c5f2, 0x1c5f4, 0x1c616, 0x1c626, + 0x1c62c, 0x1c63a, 0x1c646, 0x1c64c, 0x1c658, 0x1c66e, 0x1c672, 0x1c674, + 0x1c686, 0x1c68c, 0x1c698, 0x1c6b0, 0x1c6be, 0x1c6ce, 0x1c6dc, 0x1c6e2, + 0x1c6e4, 0x1c6e8, 0x1c712, 0x1c714, 0x1c722, 0x1c728, 0x1c736, 0x1c742, + 0x1c744, 0x1c748, 0x1c750, 0x1c75e, 0x1c766, 0x1c76c, 0x1c77a, 0x1c7ae, + 0x1c7d6, 0x1c7ea, 0x1c81a, 0x1c82e, 0x1c832, 0x1c834, 0x1c84e, 0x1c85c, + 0x1c862, 0x1c864, 0x1c868, 0x1c876, 0x1c88e, 0x1c89c, 0x1c8b8, 0x1c8c2, + 0x1c8c8, 0x1c8d0, 0x1c8de, 0x1c8e6, 0x1c8ec, 0x1c8fa, 0x1c90e, 0x1c938, + 0x1c970, 0x1c97e, 0x1c982, 0x1c984, 0x1c990, 0x1c99e, 0x1c9a0, 0x1c9bc, + 0x1c9c6, 0x1c9cc, 0x1c9d8, 0x1c9ee, 0x1c9f2, 0x1c9f4, 0x1ca38, 0x1ca70, + 0x1ca7e, 0x1cae0, 0x1cafc, 0x1cb02, 0x1cb04, 0x1cb08, 0x1cb10, 0x1cb20, + 0x1cb3c, 0x1cb40, 0x1cb78, 0x1cb86, 0x1cb8c, 0x1cb98, 0x1cbb0, 0x1cbbe, + 0x1cbce, 0x1cbdc, 0x1cbe2, 0x1cbe4, 0x1cbe8, 0x1cbf6, 0x1cc16, 0x1cc26, + 0x1cc2c, 0x1cc3a, 0x1cc46, 0x1cc58, 0x1cc72, 0x1cc74, 0x1cc86, 0x1ccb0, + 0x1ccbe, 0x1ccce, 0x1cce2, 0x1cce4, 0x1cce8, 0x1cd06, 0x1cd0c, 0x1cd18, + 0x1cd30, 0x1cd3e, 0x1cd60, 0x1cd7c, 0x1cd9c, 0x1cdc2, 0x1cdc4, 0x1cdc8, + 0x1cdd0, 0x1cdde, 0x1cde6, 0x1cdfa, 0x1ce22, 0x1ce28, 0x1ce42, 0x1ce50, + 0x1ce5e, 0x1ce66, 0x1ce7a, 0x1ce82, 0x1ce84, 0x1ce88, 0x1ce90, 0x1ce9e, + 0x1cea0, 0x1cebc, 0x1cecc, 0x1cef2, 0x1cef4, 0x1cf2e, 0x1cf32, 0x1cf34, + 0x1cf4e, 0x1cf5c, 0x1cf62, 0x1cf64, 0x1cf68, 0x1cf96, 0x1cfa6, 0x1cfac, + 0x1cfca, 0x1cfd2, 0x1cfd4, 0x1d02e, 0x1d032, 0x1d034, 0x1d04e, 0x1d05c, + 0x1d062, 0x1d064, 0x1d068, 0x1d076, 0x1d08e, 0x1d09c, 0x1d0b8, 0x1d0c2, + 0x1d0c4, 0x1d0c8, 0x1d0d0, 0x1d0de, 0x1d0e6, 0x1d0ec, 0x1d0fa, 0x1d11c, + 0x1d138, 0x1d170, 0x1d17e, 0x1d182, 0x1d184, 0x1d188, 0x1d190, 0x1d19e, + 0x1d1a0, 0x1d1bc, 0x1d1c6, 0x1d1cc, 0x1d1d8, 0x1d1ee, 0x1d1f2, 0x1d1f4, + 0x1d21c, 0x1d238, 0x1d270, 0x1d27e, 0x1d2e0, 0x1d2fc, 0x1d302, 0x1d304, + 0x1d308, 0x1d310, 0x1d31e, 0x1d320, 0x1d33c, 0x1d340, 0x1d378, 0x1d386, + 0x1d38c, 0x1d398, 0x1d3b0, 0x1d3be, 0x1d3ce, 0x1d3dc, 0x1d3e2, 0x1d3e4, + 0x1d3e8, 0x1d3f6, 0x1d470, 0x1d47e, 0x1d4e0, 0x1d4fc, 0x1d5c0, 0x1d5f8, + 0x1d604, 0x1d608, 0x1d610, 0x1d620, 0x1d640, 0x1d678, 0x1d6f0, 0x1d706, + 0x1d70c, 0x1d718, 0x1d730, 0x1d73e, 0x1d760, 0x1d77c, 0x1d78e, 0x1d79c, + 0x1d7b8, 0x1d7c2, 0x1d7c4, 0x1d7c8, 0x1d7d0, 0x1d7de, 0x1d7e6, 0x1d7ec, + 0x1d826, 0x1d82c, 0x1d83a, 0x1d846, 0x1d84c, 0x1d858, 0x1d872, 0x1d874, + 0x1d886, 0x1d88c, 0x1d898, 0x1d8b0, 0x1d8be, 0x1d8ce, 0x1d8e2, 0x1d8e4, + 0x1d8e8, 0x1d8f6, 0x1d90c, 0x1d918, 0x1d930, 0x1d93e, 0x1d960, 0x1d97c, + 0x1d99c, 0x1d9c2, 0x1d9c4, 0x1d9c8, 0x1d9d0, 0x1d9e6, 0x1d9fa, 0x1da0c, + 0x1da18, 0x1da30, 0x1da3e, 0x1da60, 0x1da7c, 0x1dac0, 0x1daf8, 0x1db38, + 0x1db82, 0x1db84, 0x1db88, 0x1db90, 0x1db9e, 0x1dba0, 0x1dbcc, 0x1dbf2, + 0x1dbf4, 0x1dc22, 0x1dc42, 0x1dc44, 0x1dc48, 0x1dc50, 0x1dc5e, 0x1dc66, + 0x1dc7a, 0x1dc82, 0x1dc84, 0x1dc88, 0x1dc90, 0x1dc9e, 0x1dca0, 0x1dcbc, + 0x1dccc, 0x1dcf2, 0x1dcf4, 0x1dd04, 0x1dd08, 0x1dd10, 0x1dd1e, 0x1dd20, + 0x1dd3c, 0x1dd40, 0x1dd78, 0x1dd86, 0x1dd98, 0x1ddce, 0x1dde2, 0x1dde4, + 0x1dde8, 0x1de2e, 0x1de32, 0x1de34, 0x1de4e, 0x1de5c, 0x1de62, 0x1de64, + 0x1de68, 0x1de8e, 0x1de9c, 0x1deb8, 0x1dec2, 0x1dec4, 0x1dec8, 0x1ded0, + 0x1dee6, 0x1defa, 0x1df16, 0x1df26, 0x1df2c, 0x1df46, 0x1df4c, 0x1df58, + 0x1df72, 0x1df74, 0x1df8a, 0x1df92, 0x1df94, 0x1dfa2, 0x1dfa4, 0x1dfa8, + 0x1e08a, 0x1e092, 0x1e094, 0x1e0a2, 0x1e0a4, 0x1e0a8, 0x1e0b6, 0x1e0da, + 0x1e10a, 0x1e112, 0x1e114, 0x1e122, 0x1e124, 0x1e128, 0x1e136, 0x1e142, + 0x1e144, 0x1e148, 0x1e150, 0x1e166, 0x1e16c, 0x1e17a, 0x1e19a, 0x1e1b2, + 0x1e1b4, 0x1e20a, 0x1e212, 0x1e214, 0x1e222, 0x1e224, 0x1e228, 0x1e236, + 0x1e242, 0x1e248, 0x1e250, 0x1e25e, 0x1e266, 0x1e26c, 0x1e27a, 0x1e282, + 0x1e284, 0x1e288, 0x1e290, 0x1e2a0, 0x1e2bc, 0x1e2c6, 0x1e2cc, 0x1e2d8, + 0x1e2ee, 0x1e2f2, 0x1e2f4, 0x1e31a, 0x1e332, 0x1e334, 0x1e35c, 0x1e362, + 0x1e364, 0x1e368, 0x1e3ba, 0x1e40a, 0x1e412, 0x1e414, 0x1e422, 0x1e428, + 0x1e436, 0x1e442, 0x1e448, 0x1e450, 0x1e45e, 0x1e466, 0x1e46c, 0x1e47a, + 0x1e482, 0x1e484, 0x1e490, 0x1e49e, 0x1e4a0, 0x1e4bc, 0x1e4c6, 0x1e4cc, + 0x1e4d8, 0x1e4ee, 0x1e4f2, 0x1e4f4, 0x1e502, 0x1e504, 0x1e508, 0x1e510, + 0x1e51e, 0x1e520, 0x1e53c, 0x1e540, 0x1e578, 0x1e586, 0x1e58c, 0x1e598, + 0x1e5b0, 0x1e5be, 0x1e5ce, 0x1e5dc, 0x1e5e2, 0x1e5e4, 0x1e5e8, 0x1e5f6, + 0x1e61a, 0x1e62e, 0x1e632, 0x1e634, 0x1e64e, 0x1e65c, 0x1e662, 0x1e668, + 0x1e68e, 0x1e69c, 0x1e6b8, 0x1e6c2, 0x1e6c4, 0x1e6c8, 0x1e6d0, 0x1e6e6, + 0x1e6fa, 0x1e716, 0x1e726, 0x1e72c, 0x1e73a, 0x1e746, 0x1e74c, 0x1e758, + 0x1e772, 0x1e774, 0x1e792, 0x1e794, 0x1e7a2, 0x1e7a4, 0x1e7a8, 0x1e7b6, + 0x1e812, 0x1e814, 0x1e822, 0x1e824, 0x1e828, 0x1e836, 0x1e842, 0x1e844, + 0x1e848, 0x1e850, 0x1e85e, 0x1e866, 0x1e86c, 0x1e87a, 0x1e882, 0x1e884, + 0x1e888, 0x1e890, 0x1e89e, 0x1e8a0, 0x1e8bc, 0x1e8c6, 0x1e8cc, 0x1e8d8, + 0x1e8ee, 0x1e8f2, 0x1e8f4, 0x1e902, 0x1e904, 0x1e908, 0x1e910, 0x1e920, + 0x1e93c, 0x1e940, 0x1e978, 0x1e986, 0x1e98c, 0x1e998, 0x1e9b0, 0x1e9be, + 0x1e9ce, 0x1e9dc, 0x1e9e2, 0x1e9e4, 0x1e9e8, 0x1e9f6, 0x1ea04, 0x1ea08, + 0x1ea10, 0x1ea20, 0x1ea40, 0x1ea78, 0x1eaf0, 0x1eb06, 0x1eb0c, 0x1eb18, + 0x1eb30, 0x1eb3e, 0x1eb60, 0x1eb7c, 0x1eb8e, 0x1eb9c, 0x1ebb8, 0x1ebc2, + 0x1ebc4, 0x1ebc8, 0x1ebd0, 0x1ebde, 0x1ebe6, 0x1ebec, 0x1ec1a, 0x1ec2e, + 0x1ec32, 0x1ec34, 0x1ec4e, 0x1ec5c, 0x1ec62, 0x1ec64, 0x1ec68, 0x1ec8e, + 0x1ec9c, 0x1ecb8, 0x1ecc2, 0x1ecc4, 0x1ecc8, 0x1ecd0, 0x1ece6, 0x1ecfa, + 0x1ed0e, 0x1ed1c, 0x1ed38, 0x1ed70, 0x1ed7e, 0x1ed82, 0x1ed84, 0x1ed88, + 0x1ed90, 0x1ed9e, 0x1eda0, 0x1edcc, 0x1edf2, 0x1edf4, 0x1ee16, 0x1ee26, + 0x1ee2c, 0x1ee3a, 0x1ee46, 0x1ee4c, 0x1ee58, 0x1ee6e, 0x1ee72, 0x1ee74, + 0x1ee86, 0x1ee8c, 0x1ee98, 0x1eeb0, 0x1eebe, 0x1eece, 0x1eedc, 0x1eee2, + 0x1eee4, 0x1eee8, 0x1ef12, 0x1ef22, 0x1ef24, 0x1ef28, 0x1ef36, 0x1ef42, + 0x1ef44, 0x1ef48, 0x1ef50, 0x1ef5e, 0x1ef66, 0x1ef6c, 0x1ef7a, 0x1efae, + 0x1efb2, 0x1efb4, 0x1efd6, 0x1f096, 0x1f0a6, 0x1f0ac, 0x1f0ba, 0x1f0ca, + 0x1f0d2, 0x1f0d4, 0x1f116, 0x1f126, 0x1f12c, 0x1f13a, 0x1f146, 0x1f14c, + 0x1f158, 0x1f16e, 0x1f172, 0x1f174, 0x1f18a, 0x1f192, 0x1f194, 0x1f1a2, + 0x1f1a4, 0x1f1a8, 0x1f1da, 0x1f216, 0x1f226, 0x1f22c, 0x1f23a, 0x1f246, + 0x1f258, 0x1f26e, 0x1f272, 0x1f274, 0x1f286, 0x1f28c, 0x1f298, 0x1f2b0, + 0x1f2be, 0x1f2ce, 0x1f2dc, 0x1f2e2, 0x1f2e4, 0x1f2e8, 0x1f2f6, 0x1f30a, + 0x1f312, 0x1f314, 0x1f322, 0x1f328, 0x1f342, 0x1f344, 0x1f348, 0x1f350, + 0x1f35e, 0x1f366, 0x1f37a, 0x1f39a, 0x1f3ae, 0x1f3b2, 0x1f3b4, 0x1f416, + 0x1f426, 0x1f42c, 0x1f43a, 0x1f446, 0x1f44c, 0x1f458, 0x1f46e, 0x1f472, + 0x1f474, 0x1f486, 0x1f48c, 0x1f498, 0x1f4b0, 0x1f4be, 0x1f4ce, 0x1f4dc, + 0x1f4e2, 0x1f4e4, 0x1f4e8, 0x1f4f6, 0x1f506, 0x1f50c, 0x1f518, 0x1f530, + 0x1f53e, 0x1f560, 0x1f57c, 0x1f58e, 0x1f59c, 0x1f5b8, 0x1f5c2, 0x1f5c4, + 0x1f5c8, 0x1f5d0, 0x1f5de, 0x1f5e6, 0x1f5ec, 0x1f5fa, 0x1f60a, 0x1f612, + 0x1f614, 0x1f622, 0x1f624, 0x1f628, 0x1f636, 0x1f642, 0x1f644, 0x1f648, + 0x1f650, 0x1f65e, 0x1f666, 0x1f67a, 0x1f682, 0x1f684, 0x1f688, 0x1f690, + 0x1f69e, 0x1f6a0, 0x1f6bc, 0x1f6cc, 0x1f6f2, 0x1f6f4, 0x1f71a, 0x1f72e, + 0x1f732, 0x1f734, 0x1f74e, 0x1f75c, 0x1f762, 0x1f764, 0x1f768, 0x1f776, + 0x1f796, 0x1f7a6, 0x1f7ac, 0x1f7ba, 0x1f7d2, 0x1f7d4, 0x1f89a, 0x1f8ae, + 0x1f8b2, 0x1f8b4, 0x1f8d6, 0x1f8ea, 0x1f91a, 0x1f92e, 0x1f932, 0x1f934, + 0x1f94e, 0x1f95c, 0x1f962, 0x1f964, 0x1f968, 0x1f976, 0x1f996, 0x1f9a6, + 0x1f9ac, 0x1f9ba, 0x1f9ca, 0x1f9d2, 0x1f9d4, 0x1fa1a, 0x1fa2e, 0x1fa32, + 0x1fa34, 0x1fa4e, 0x1fa5c, 0x1fa62, 0x1fa64, 0x1fa68, 0x1fa76, 0x1fa8e, + 0x1fa9c, 0x1fab8, 0x1fac2, 0x1fac4, 0x1fac8, 0x1fad0, 0x1fade, 0x1fae6, + 0x1faec, 0x1fb16, 0x1fb26, 0x1fb2c, 0x1fb3a, 0x1fb46, 0x1fb4c, 0x1fb58, + 0x1fb6e, 0x1fb72, 0x1fb74, 0x1fb8a, 0x1fb92, 0x1fb94, 0x1fba2, 0x1fba4, + 0x1fba8, 0x1fbb6, 0x1fbda}; +int32_t CBC_PDF417Common::CODEWORD_TABLE[] = { + 2627, 1819, 2622, 2621, 1813, 1812, 2729, 2724, 2723, 2779, 2774, 2773, + 902, 896, 908, 868, 865, 861, 859, 2511, 873, 871, 1780, 835, + 2493, 825, 2491, 842, 837, 844, 1764, 1762, 811, 810, 809, 2483, + 807, 2482, 806, 2480, 815, 814, 813, 812, 2484, 817, 816, 1745, + 1744, 1742, 1746, 2655, 2637, 2635, 2626, 2625, 2623, 2628, 1820, 2752, + 2739, 2737, 2728, 2727, 2725, 2730, 2785, 2783, 2778, 2777, 2775, 2780, + 787, 781, 747, 739, 736, 2413, 754, 752, 1719, 692, 689, 681, + 2371, 678, 2369, 700, 697, 694, 703, 1688, 1686, 642, 638, 2343, + 631, 2341, 627, 2338, 651, 646, 643, 2345, 654, 652, 1652, 1650, + 1647, 1654, 601, 599, 2322, 596, 2321, 594, 2319, 2317, 611, 610, + 608, 606, 2324, 603, 2323, 615, 614, 612, 1617, 1616, 1614, 1612, + 616, 1619, 1618, 2575, 2538, 2536, 905, 901, 898, 909, 2509, 2507, + 2504, 870, 867, 864, 860, 2512, 875, 872, 1781, 2490, 2489, 2487, + 2485, 1748, 836, 834, 832, 830, 2494, 827, 2492, 843, 841, 839, + 845, 1765, 1763, 2701, 2676, 2674, 2653, 2648, 2656, 2634, 2633, 2631, + 2629, 1821, 2638, 2636, 2770, 2763, 2761, 2750, 2745, 2753, 2736, 2735, + 2733, 2731, 1848, 2740, 2738, 2786, 2784, 591, 588, 576, 569, 566, + 2296, 1590, 537, 534, 526, 2276, 522, 2274, 545, 542, 539, 548, + 1572, 1570, 481, 2245, 466, 2242, 462, 2239, 492, 485, 482, 2249, + 496, 494, 1534, 1531, 1528, 1538, 413, 2196, 406, 2191, 2188, 425, + 419, 2202, 415, 2199, 432, 430, 427, 1472, 1467, 1464, 433, 1476, + 1474, 368, 367, 2160, 365, 2159, 362, 2157, 2155, 2152, 378, 377, + 375, 2166, 372, 2165, 369, 2162, 383, 381, 379, 2168, 1419, 1418, + 1416, 1414, 385, 1411, 384, 1423, 1422, 1420, 1424, 2461, 802, 2441, + 2439, 790, 786, 783, 794, 2409, 2406, 2403, 750, 742, 738, 2414, + 756, 753, 1720, 2367, 2365, 2362, 2359, 1663, 693, 691, 684, 2373, + 680, 2370, 702, 699, 696, 704, 1690, 1687, 2337, 2336, 2334, 2332, + 1624, 2329, 1622, 640, 637, 2344, 634, 2342, 630, 2340, 650, 648, + 645, 2346, 655, 653, 1653, 1651, 1649, 1655, 2612, 2597, 2595, 2571, + 2568, 2565, 2576, 2534, 2529, 2526, 1787, 2540, 2537, 907, 904, 900, + 910, 2503, 2502, 2500, 2498, 1768, 2495, 1767, 2510, 2508, 2506, 869, + 866, 863, 2513, 876, 874, 1782, 2720, 2713, 2711, 2697, 2694, 2691, + 2702, 2672, 2670, 2664, 1828, 2678, 2675, 2647, 2646, 2644, 2642, 1823, + 2639, 1822, 2654, 2652, 2650, 2657, 2771, 1855, 2765, 2762, 1850, 1849, + 2751, 2749, 2747, 2754, 353, 2148, 344, 342, 336, 2142, 332, 2140, + 345, 1375, 1373, 306, 2130, 299, 2128, 295, 2125, 319, 314, 311, + 2132, 1354, 1352, 1349, 1356, 262, 257, 2101, 253, 2096, 2093, 274, + 273, 267, 2107, 263, 2104, 280, 278, 275, 1316, 1311, 1308, 1320, + 1318, 2052, 202, 2050, 2044, 2040, 219, 2063, 212, 2060, 208, 2055, + 224, 221, 2066, 1260, 1258, 1252, 231, 1248, 229, 1266, 1264, 1261, + 1268, 155, 1998, 153, 1996, 1994, 1991, 1988, 165, 164, 2007, 162, + 2006, 159, 2003, 2000, 172, 171, 169, 2012, 166, 2010, 1186, 1184, + 1182, 1179, 175, 1176, 173, 1192, 1191, 1189, 1187, 176, 1194, 1193, + 2313, 2307, 2305, 592, 589, 2294, 2292, 2289, 578, 572, 568, 2297, + 580, 1591, 2272, 2267, 2264, 1547, 538, 536, 529, 2278, 525, 2275, + 547, 544, 541, 1574, 1571, 2237, 2235, 2229, 1493, 2225, 1489, 478, + 2247, 470, 2244, 465, 2241, 493, 488, 484, 2250, 498, 495, 1536, + 1533, 1530, 1539, 2187, 2186, 2184, 2182, 1432, 2179, 1430, 2176, 1427, + 414, 412, 2197, 409, 2195, 405, 2193, 2190, 426, 424, 421, 2203, + 418, 2201, 431, 429, 1473, 1471, 1469, 1466, 434, 1477, 1475, 2478, + 2472, 2470, 2459, 2457, 2454, 2462, 803, 2437, 2432, 2429, 1726, 2443, + 2440, 792, 789, 785, 2401, 2399, 2393, 1702, 2389, 1699, 2411, 2408, + 2405, 745, 741, 2415, 758, 755, 1721, 2358, 2357, 2355, 2353, 1661, + 2350, 1660, 2347, 1657, 2368, 2366, 2364, 2361, 1666, 690, 687, 2374, + 683, 2372, 701, 698, 705, 1691, 1689, 2619, 2617, 2610, 2608, 2605, + 2613, 2593, 2588, 2585, 1803, 2599, 2596, 2563, 2561, 2555, 1797, 2551, + 1795, 2573, 2570, 2567, 2577, 2525, 2524, 2522, 2520, 1786, 2517, 1785, + 2514, 1783, 2535, 2533, 2531, 2528, 1788, 2541, 2539, 906, 903, 911, + 2721, 1844, 2715, 2712, 1838, 1836, 2699, 2696, 2693, 2703, 1827, 1826, + 1824, 2673, 2671, 2669, 2666, 1829, 2679, 2677, 1858, 1857, 2772, 1854, + 1853, 1851, 1856, 2766, 2764, 143, 1987, 139, 1986, 135, 133, 131, + 1984, 128, 1983, 125, 1981, 138, 137, 136, 1985, 1133, 1132, 1130, + 112, 110, 1974, 107, 1973, 104, 1971, 1969, 122, 121, 119, 117, + 1977, 114, 1976, 124, 1115, 1114, 1112, 1110, 1117, 1116, 84, 83, + 1953, 81, 1952, 78, 1950, 1948, 1945, 94, 93, 91, 1959, 88, + 1958, 85, 1955, 99, 97, 95, 1961, 1086, 1085, 1083, 1081, 1078, + 100, 1090, 1089, 1087, 1091, 49, 47, 1917, 44, 1915, 1913, 1910, + 1907, 59, 1926, 56, 1925, 53, 1922, 1919, 66, 64, 1931, 61, + 1929, 1042, 1040, 1038, 71, 1035, 70, 1032, 68, 1048, 1047, 1045, + 1043, 1050, 1049, 12, 10, 1869, 1867, 1864, 1861, 21, 1880, 19, + 1877, 1874, 1871, 28, 1888, 25, 1886, 22, 1883, 982, 980, 977, + 974, 32, 30, 991, 989, 987, 984, 34, 995, 994, 992, 2151, + 2150, 2147, 2146, 2144, 356, 355, 354, 2149, 2139, 2138, 2136, 2134, + 1359, 343, 341, 338, 2143, 335, 2141, 348, 347, 346, 1376, 1374, + 2124, 2123, 2121, 2119, 1326, 2116, 1324, 310, 308, 305, 2131, 302, + 2129, 298, 2127, 320, 318, 316, 313, 2133, 322, 321, 1355, 1353, + 1351, 1357, 2092, 2091, 2089, 2087, 1276, 2084, 1274, 2081, 1271, 259, + 2102, 256, 2100, 252, 2098, 2095, 272, 269, 2108, 266, 2106, 281, + 279, 277, 1317, 1315, 1313, 1310, 282, 1321, 1319, 2039, 2037, 2035, + 2032, 1203, 2029, 1200, 1197, 207, 2053, 205, 2051, 201, 2049, 2046, + 2043, 220, 218, 2064, 215, 2062, 211, 2059, 228, 226, 223, 2069, + 1259, 1257, 1254, 232, 1251, 230, 1267, 1265, 1263, 2316, 2315, 2312, + 2311, 2309, 2314, 2304, 2303, 2301, 2299, 1593, 2308, 2306, 590, 2288, + 2287, 2285, 2283, 1578, 2280, 1577, 2295, 2293, 2291, 579, 577, 574, + 571, 2298, 582, 581, 1592, 2263, 2262, 2260, 2258, 1545, 2255, 1544, + 2252, 1541, 2273, 2271, 2269, 2266, 1550, 535, 532, 2279, 528, 2277, + 546, 543, 549, 1575, 1573, 2224, 2222, 2220, 1486, 2217, 1485, 2214, + 1482, 1479, 2238, 2236, 2234, 2231, 1496, 2228, 1492, 480, 477, 2248, + 473, 2246, 469, 2243, 490, 487, 2251, 497, 1537, 1535, 1532, 2477, + 2476, 2474, 2479, 2469, 2468, 2466, 2464, 1730, 2473, 2471, 2453, 2452, + 2450, 2448, 1729, 2445, 1728, 2460, 2458, 2456, 2463, 805, 804, 2428, + 2427, 2425, 2423, 1725, 2420, 1724, 2417, 1722, 2438, 2436, 2434, 2431, + 1727, 2444, 2442, 793, 791, 788, 795, 2388, 2386, 2384, 1697, 2381, + 1696, 2378, 1694, 1692, 2402, 2400, 2398, 2395, 1703, 2392, 1701, 2412, + 2410, 2407, 751, 748, 744, 2416, 759, 757, 1807, 2620, 2618, 1806, + 1805, 2611, 2609, 2607, 2614, 1802, 1801, 1799, 2594, 2592, 2590, 2587, + 1804, 2600, 2598, 1794, 1793, 1791, 1789, 2564, 2562, 2560, 2557, 1798, + 2554, 1796, 2574, 2572, 2569, 2578, 1847, 1846, 2722, 1843, 1842, 1840, + 1845, 2716, 2714, 1835, 1834, 1832, 1830, 1839, 1837, 2700, 2698, 2695, + 2704, 1817, 1811, 1810, 897, 862, 1777, 829, 826, 838, 1760, 1758, + 808, 2481, 1741, 1740, 1738, 1743, 2624, 1818, 2726, 2776, 782, 740, + 737, 1715, 686, 679, 695, 1682, 1680, 639, 628, 2339, 647, 644, + 1645, 1643, 1640, 1648, 602, 600, 597, 595, 2320, 593, 2318, 609, + 607, 604, 1611, 1610, 1608, 1606, 613, 1615, 1613, 2328, 926, 924, + 892, 886, 899, 857, 850, 2505, 1778, 824, 823, 821, 819, 2488, + 818, 2486, 833, 831, 828, 840, 1761, 1759, 2649, 2632, 2630, 2746, + 2734, 2732, 2782, 2781, 570, 567, 1587, 531, 527, 523, 540, 1566, + 1564, 476, 467, 463, 2240, 486, 483, 1524, 1521, 1518, 1529, 411, + 403, 2192, 399, 2189, 423, 416, 1462, 1457, 1454, 428, 1468, 1465, + 2210, 366, 363, 2158, 360, 2156, 357, 2153, 376, 373, 370, 2163, + 1410, 1409, 1407, 1405, 382, 1402, 380, 1417, 1415, 1412, 1421, 2175, + 2174, 777, 774, 771, 784, 732, 725, 722, 2404, 743, 1716, 676, + 674, 668, 2363, 665, 2360, 685, 1684, 1681, 626, 624, 622, 2335, + 620, 2333, 617, 2330, 641, 635, 649, 1646, 1644, 1642, 2566, 928, + 925, 2530, 2527, 894, 891, 888, 2501, 2499, 2496, 858, 856, 854, + 851, 1779, 2692, 2668, 2665, 2645, 2643, 2640, 2651, 2768, 2759, 2757, + 2744, 2743, 2741, 2748, 352, 1382, 340, 337, 333, 1371, 1369, 307, + 300, 296, 2126, 315, 312, 1347, 1342, 1350, 261, 258, 250, 2097, + 246, 2094, 271, 268, 264, 1306, 1301, 1298, 276, 1312, 1309, 2115, + 203, 2048, 195, 2045, 191, 2041, 213, 209, 2056, 1246, 1244, 1238, + 225, 1234, 222, 1256, 1253, 1249, 1262, 2080, 2079, 154, 1997, 150, + 1995, 147, 1992, 1989, 163, 160, 2004, 156, 2001, 1175, 1174, 1172, + 1170, 1167, 170, 1164, 167, 1185, 1183, 1180, 1177, 174, 1190, 1188, + 2025, 2024, 2022, 587, 586, 564, 559, 556, 2290, 573, 1588, 520, + 518, 512, 2268, 508, 2265, 530, 1568, 1565, 461, 457, 2233, 450, + 2230, 446, 2226, 479, 471, 489, 1526, 1523, 1520, 397, 395, 2185, + 392, 2183, 389, 2180, 2177, 410, 2194, 402, 422, 1463, 1461, 1459, + 1456, 1470, 2455, 799, 2433, 2430, 779, 776, 773, 2397, 2394, 2390, + 734, 728, 724, 746, 1717, 2356, 2354, 2351, 2348, 1658, 677, 675, + 673, 670, 667, 688, 1685, 1683, 2606, 2589, 2586, 2559, 2556, 2552, + 927, 2523, 2521, 2518, 2515, 1784, 2532, 895, 893, 890, 2718, 2709, + 2707, 2689, 2687, 2684, 2663, 2662, 2660, 2658, 1825, 2667, 2769, 1852, + 2760, 2758, 142, 141, 1139, 1138, 134, 132, 129, 126, 1982, 1129, + 1128, 1126, 1131, 113, 111, 108, 105, 1972, 101, 1970, 120, 118, + 115, 1109, 1108, 1106, 1104, 123, 1113, 1111, 82, 79, 1951, 75, + 1949, 72, 1946, 92, 89, 86, 1956, 1077, 1076, 1074, 1072, 98, + 1069, 96, 1084, 1082, 1079, 1088, 1968, 1967, 48, 45, 1916, 42, + 1914, 39, 1911, 1908, 60, 57, 54, 1923, 50, 1920, 1031, 1030, + 1028, 1026, 67, 1023, 65, 1020, 62, 1041, 1039, 1036, 1033, 69, + 1046, 1044, 1944, 1943, 1941, 11, 9, 1868, 7, 1865, 1862, 1859, + 20, 1878, 16, 1875, 13, 1872, 970, 968, 966, 963, 29, 960, + 26, 23, 983, 981, 978, 975, 33, 971, 31, 990, 988, 985, + 1906, 1904, 1902, 993, 351, 2145, 1383, 331, 330, 328, 326, 2137, + 323, 2135, 339, 1372, 1370, 294, 293, 291, 289, 2122, 286, 2120, + 283, 2117, 309, 303, 317, 1348, 1346, 1344, 245, 244, 242, 2090, + 239, 2088, 236, 2085, 2082, 260, 2099, 249, 270, 1307, 1305, 1303, + 1300, 1314, 189, 2038, 186, 2036, 183, 2033, 2030, 2026, 206, 198, + 2047, 194, 216, 1247, 1245, 1243, 1240, 227, 1237, 1255, 2310, 2302, + 2300, 2286, 2284, 2281, 565, 563, 561, 558, 575, 1589, 2261, 2259, + 2256, 2253, 1542, 521, 519, 517, 514, 2270, 511, 533, 1569, 1567, + 2223, 2221, 2218, 2215, 1483, 2211, 1480, 459, 456, 453, 2232, 449, + 474, 491, 1527, 1525, 1522, 2475, 2467, 2465, 2451, 2449, 2446, 801, + 800, 2426, 2424, 2421, 2418, 1723, 2435, 780, 778, 775, 2387, 2385, + 2382, 2379, 1695, 2375, 1693, 2396, 735, 733, 730, 727, 749, 1718, + 2616, 2615, 2604, 2603, 2601, 2584, 2583, 2581, 2579, 1800, 2591, 2550, + 2549, 2547, 2545, 1792, 2542, 1790, 2558, 929, 2719, 1841, 2710, 2708, + 1833, 1831, 2690, 2688, 2686, 1815, 1809, 1808, 1774, 1756, 1754, 1737, + 1736, 1734, 1739, 1816, 1711, 1676, 1674, 633, 629, 1638, 1636, 1633, + 1641, 598, 1605, 1604, 1602, 1600, 605, 1609, 1607, 2327, 887, 853, + 1775, 822, 820, 1757, 1755, 1584, 524, 1560, 1558, 468, 464, 1514, + 1511, 1508, 1519, 408, 404, 400, 1452, 1447, 1444, 417, 1458, 1455, + 2208, 364, 361, 358, 2154, 1401, 1400, 1398, 1396, 374, 1393, 371, + 1408, 1406, 1403, 1413, 2173, 2172, 772, 726, 723, 1712, 672, 669, + 666, 682, 1678, 1675, 625, 623, 621, 618, 2331, 636, 632, 1639, + 1637, 1635, 920, 918, 884, 880, 889, 849, 848, 847, 846, 2497, + 855, 852, 1776, 2641, 2742, 2787, 1380, 334, 1367, 1365, 301, 297, + 1340, 1338, 1335, 1343, 255, 251, 247, 1296, 1291, 1288, 265, 1302, + 1299, 2113, 204, 196, 192, 2042, 1232, 1230, 1224, 214, 1220, 210, + 1242, 1239, 1235, 1250, 2077, 2075, 151, 148, 1993, 144, 1990, 1163, + 1162, 1160, 1158, 1155, 161, 1152, 157, 1173, 1171, 1168, 1165, 168, + 1181, 1178, 2021, 2020, 2018, 2023, 585, 560, 557, 1585, 516, 509, + 1562, 1559, 458, 447, 2227, 472, 1516, 1513, 1510, 398, 396, 393, + 390, 2181, 386, 2178, 407, 1453, 1451, 1449, 1446, 420, 1460, 2209, + 769, 764, 720, 712, 2391, 729, 1713, 664, 663, 661, 659, 2352, + 656, 2349, 671, 1679, 1677, 2553, 922, 919, 2519, 2516, 885, 883, + 881, 2685, 2661, 2659, 2767, 2756, 2755, 140, 1137, 1136, 130, 127, + 1125, 1124, 1122, 1127, 109, 106, 102, 1103, 1102, 1100, 1098, 116, + 1107, 1105, 1980, 80, 76, 73, 1947, 1068, 1067, 1065, 1063, 90, + 1060, 87, 1075, 1073, 1070, 1080, 1966, 1965, 46, 43, 40, 1912, + 36, 1909, 1019, 1018, 1016, 1014, 58, 1011, 55, 1008, 51, 1029, + 1027, 1024, 1021, 63, 1037, 1034, 1940, 1939, 1937, 1942, 8, 1866, + 4, 1863, 1, 1860, 956, 954, 952, 949, 946, 17, 14, 969, + 967, 964, 961, 27, 957, 24, 979, 976, 972, 1901, 1900, 1898, + 1896, 986, 1905, 1903, 350, 349, 1381, 329, 327, 324, 1368, 1366, + 292, 290, 287, 284, 2118, 304, 1341, 1339, 1337, 1345, 243, 240, + 237, 2086, 233, 2083, 254, 1297, 1295, 1293, 1290, 1304, 2114, 190, + 187, 184, 2034, 180, 2031, 177, 2027, 199, 1233, 1231, 1229, 1226, + 217, 1223, 1241, 2078, 2076, 584, 555, 554, 552, 550, 2282, 562, + 1586, 507, 506, 504, 502, 2257, 499, 2254, 515, 1563, 1561, 445, + 443, 441, 2219, 438, 2216, 435, 2212, 460, 454, 475, 1517, 1515, + 1512, 2447, 798, 797, 2422, 2419, 770, 768, 766, 2383, 2380, 2376, + 721, 719, 717, 714, 731, 1714, 2602, 2582, 2580, 2548, 2546, 2543, + 923, 921, 2717, 2706, 2705, 2683, 2682, 2680, 1771, 1752, 1750, 1733, + 1732, 1731, 1735, 1814, 1707, 1670, 1668, 1631, 1629, 1626, 1634, 1599, + 1598, 1596, 1594, 1603, 1601, 2326, 1772, 1753, 1751, 1581, 1554, 1552, + 1504, 1501, 1498, 1509, 1442, 1437, 1434, 401, 1448, 1445, 2206, 1392, + 1391, 1389, 1387, 1384, 359, 1399, 1397, 1394, 1404, 2171, 2170, 1708, + 1672, 1669, 619, 1632, 1630, 1628, 1773, 1378, 1363, 1361, 1333, 1328, + 1336, 1286, 1281, 1278, 248, 1292, 1289, 2111, 1218, 1216, 1210, 197, + 1206, 193, 1228, 1225, 1221, 1236, 2073, 2071, 1151, 1150, 1148, 1146, + 152, 1143, 149, 1140, 145, 1161, 1159, 1156, 1153, 158, 1169, 1166, + 2017, 2016, 2014, 2019, 1582, 510, 1556, 1553, 452, 448, 1506, 1500, + 394, 391, 387, 1443, 1441, 1439, 1436, 1450, 2207, 765, 716, 713, + 1709, 662, 660, 657, 1673, 1671, 916, 914, 879, 878, 877, 882, + 1135, 1134, 1121, 1120, 1118, 1123, 1097, 1096, 1094, 1092, 103, 1101, + 1099, 1979, 1059, 1058, 1056, 1054, 77, 1051, 74, 1066, 1064, 1061, + 1071, 1964, 1963, 1007, 1006, 1004, 1002, 999, 41, 996, 37, 1017, + 1015, 1012, 1009, 52, 1025, 1022, 1936, 1935, 1933, 1938, 942, 940, + 938, 935, 932, 5, 2, 955, 953, 950, 947, 18, 943, 15, + 965, 962, 958, 1895, 1894, 1892, 1890, 973, 1899, 1897, 1379, 325, + 1364, 1362, 288, 285, 1334, 1332, 1330, 241, 238, 234, 1287, 1285, + 1283, 1280, 1294, 2112, 188, 185, 181, 178, 2028, 1219, 1217, 1215, + 1212, 200, 1209, 1227, 2074, 2072, 583, 553, 551, 1583, 505, 503, + 500, 513, 1557, 1555, 444, 442, 439, 436, 2213, 455, 451, 1507, + 1505, 1502, 796, 763, 762, 760, 767, 711, 710, 708, 706, 2377, + 718, 715, 1710, 2544, 917, 915, 2681, 1627, 1597, 1595, 2325, 1769, + 1749, 1747, 1499, 1438, 1435, 2204, 1390, 1388, 1385, 1395, 2169, 2167, + 1704, 1665, 1662, 1625, 1623, 1620, 1770, 1329, 1282, 1279, 2109, 1214, + 1207, 1222, 2068, 2065, 1149, 1147, 1144, 1141, 146, 1157, 1154, 2013, + 2011, 2008, 2015, 1579, 1549, 1546, 1495, 1487, 1433, 1431, 1428, 1425, + 388, 1440, 2205, 1705, 658, 1667, 1664, 1119, 1095, 1093, 1978, 1057, + 1055, 1052, 1062, 1962, 1960, 1005, 1003, 1000, 997, 38, 1013, 1010, + 1932, 1930, 1927, 1934, 941, 939, 936, 933, 6, 930, 3, 951, + 948, 944, 1889, 1887, 1884, 1881, 959, 1893, 1891, 35, 1377, 1360, + 1358, 1327, 1325, 1322, 1331, 1277, 1275, 1272, 1269, 235, 1284, 2110, + 1205, 1204, 1201, 1198, 182, 1195, 179, 1213, 2070, 2067, 1580, 501, + 1551, 1548, 440, 437, 1497, 1494, 1490, 1503, 761, 709, 707, 1706, + 913, 912, 2198, 1386, 2164, 2161, 1621, 1766, 2103, 1208, 2058, 2054, + 1145, 1142, 2005, 2002, 1999, 2009, 1488, 1429, 1426, 2200, 1698, 1659, + 1656, 1975, 1053, 1957, 1954, 1001, 998, 1924, 1921, 1918, 1928, 937, + 934, 931, 1879, 1876, 1873, 1870, 945, 1885, 1882, 1323, 1273, 1270, + 2105, 1202, 1199, 1196, 1211, 2061, 2057, 1576, 1543, 1540, 1484, 1481, + 1478, 1491, 1700}; + +CBC_PDF417Common::CBC_PDF417Common() {} +CBC_PDF417Common::~CBC_PDF417Common() {} +int32_t CBC_PDF417Common::getBitCountSum(CFX_Int32Array& moduleBitCount) { + int32_t bitCountSum = 0; + for (int32_t i = 0; i < moduleBitCount.GetSize(); i++) { + int32_t count = moduleBitCount.GetAt(i); + bitCountSum += count; + } + return bitCountSum; +} +int32_t CBC_PDF417Common::getCodeword(FX_DWORD symbol) { + FX_DWORD sym = symbol & 0x3FFFF; + int32_t i = findCodewordIndex(sym); + if (i == -1) { + return -1; + } + return (CODEWORD_TABLE[i] - 1) % NUMBER_OF_CODEWORDS; +} +int32_t CBC_PDF417Common::findCodewordIndex(FX_DWORD symbol) { + int32_t first = 0; + int32_t upto = sizeof(SYMBOL_TABLE) / sizeof(SYMBOL_TABLE[0]); + while (first < upto) { + int32_t mid = ((FX_DWORD)(first + upto)) >> 1; + if (symbol < (FX_DWORD)SYMBOL_TABLE[mid]) { + upto = mid; + } else if (symbol > (FX_DWORD)SYMBOL_TABLE[mid]) { + first = mid + 1; + } else { + return mid; + } + } + return -1; +} diff --git a/xfa/fxbarcode/pdf417/BC_PDF417Common.h b/xfa/fxbarcode/pdf417/BC_PDF417Common.h new file mode 100644 index 0000000000..61e93ab759 --- /dev/null +++ b/xfa/fxbarcode/pdf417/BC_PDF417Common.h @@ -0,0 +1,34 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef XFA_FXBARCODE_PDF417_BC_PDF417COMMON_H_ +#define XFA_FXBARCODE_PDF417_BC_PDF417COMMON_H_ + +#include "core/include/fxcrt/fx_basic.h" + +class CBC_PDF417Common { + public: + CBC_PDF417Common(); + virtual ~CBC_PDF417Common(); + static int32_t getBitCountSum(CFX_Int32Array& moduleBitCount); + static int32_t getCodeword(FX_DWORD symbol); + static int32_t NUMBER_OF_CODEWORDS; + static int32_t MAX_CODEWORDS_IN_BARCODE; + static int32_t MIN_ROWS_IN_BARCODE; + static int32_t MAX_ROWS_IN_BARCODE; + static int32_t MAX_CODEWORDS_IN_ROW; + static int32_t MODULES_IN_CODEWORD; + static int32_t MODULES_IN_STOP_PATTERN; + static int32_t BARS_IN_MODULE; + static int32_t SYMBOL_TABLE[]; + static int32_t CODEWORD_TABLE[]; + + private: + static CFX_Int32Array* EMPTY_INT_ARRAY; + static int32_t findCodewordIndex(FX_DWORD symbol); +}; + +#endif // XFA_FXBARCODE_PDF417_BC_PDF417COMMON_H_ diff --git a/xfa/fxbarcode/pdf417/BC_PDF417Compaction.cpp b/xfa/fxbarcode/pdf417/BC_PDF417Compaction.cpp new file mode 100644 index 0000000000..d3a1663eb6 --- /dev/null +++ b/xfa/fxbarcode/pdf417/BC_PDF417Compaction.cpp @@ -0,0 +1,26 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com +// Original code is licensed as follows: +/* + * Copyright 2011 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "xfa/fxbarcode/pdf417/BC_PDF417Compaction.h" + +CBC_Compaction::CBC_Compaction() {} +CBC_Compaction::~CBC_Compaction() {} diff --git a/xfa/fxbarcode/pdf417/BC_PDF417Compaction.h b/xfa/fxbarcode/pdf417/BC_PDF417Compaction.h new file mode 100644 index 0000000000..2df0fce303 --- /dev/null +++ b/xfa/fxbarcode/pdf417/BC_PDF417Compaction.h @@ -0,0 +1,18 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef XFA_FXBARCODE_PDF417_BC_PDF417COMPACTION_H_ +#define XFA_FXBARCODE_PDF417_BC_PDF417COMPACTION_H_ + +class CBC_Compaction; +enum Compaction { AUTO, TEXT, BYTES, NUMERIC }; +class CBC_Compaction { + public: + CBC_Compaction(); + virtual ~CBC_Compaction(); +}; + +#endif // XFA_FXBARCODE_PDF417_BC_PDF417COMPACTION_H_ diff --git a/xfa/fxbarcode/pdf417/BC_PDF417DecodedBitStreamParser.cpp b/xfa/fxbarcode/pdf417/BC_PDF417DecodedBitStreamParser.cpp new file mode 100644 index 0000000000..d52648c683 --- /dev/null +++ b/xfa/fxbarcode/pdf417/BC_PDF417DecodedBitStreamParser.cpp @@ -0,0 +1,493 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com +// Original code is licensed as follows: +/* + * Copyright 2009 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "xfa/fxbarcode/pdf417/BC_PDF417DecodedBitStreamParser.h" + +#include <stdlib.h> + +#include "third_party/bigint/BigIntegerLibrary.hh" +#include "xfa/fxbarcode/BC_DecoderResult.h" +#include "xfa/fxbarcode/common/BC_CommonDecoderResult.h" +#include "xfa/fxbarcode/pdf417/BC_PDF417ResultMetadata.h" +#include "xfa/fxbarcode/utils.h" + +#define TEXT_COMPACTION_MODE_LATCH 900 +#define BYTE_COMPACTION_MODE_LATCH 901 +#define NUMERIC_COMPACTION_MODE_LATCH 902 +#define BYTE_COMPACTION_MODE_LATCH_6 924 +#define BEGIN_MACRO_PDF417_CONTROL_BLOCK 928 +#define BEGIN_MACRO_PDF417_OPTIONAL_FIELD 923 +#define MACRO_PDF417_TERMINATOR 922 +#define MODE_SHIFT_TO_BYTE_COMPACTION_MODE 913 + +int32_t CBC_DecodedBitStreamPaser::MAX_NUMERIC_CODEWORDS = 15; +int32_t CBC_DecodedBitStreamPaser::NUMBER_OF_SEQUENCE_CODEWORDS = 2; +int32_t CBC_DecodedBitStreamPaser::PL = 25; +int32_t CBC_DecodedBitStreamPaser::LL = 27; +int32_t CBC_DecodedBitStreamPaser::AS = 27; +int32_t CBC_DecodedBitStreamPaser::ML = 28; +int32_t CBC_DecodedBitStreamPaser::AL = 28; +int32_t CBC_DecodedBitStreamPaser::PS = 29; +int32_t CBC_DecodedBitStreamPaser::PAL = 29; +FX_CHAR CBC_DecodedBitStreamPaser::PUNCT_CHARS[29] = { + ';', '<', '>', '@', '[', '\\', '}', '_', '`', '~', + '!', '\r', '\t', ',', ':', '\n', '-', '.', '$', '/', + '"', '|', '*', '(', ')', '?', '{', '}', '\''}; +FX_CHAR CBC_DecodedBitStreamPaser::MIXED_CHARS[30] = { + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '&', '\r', '\t', + ',', ':', '#', '-', '.', '$', '/', '+', '%', '*', '=', '^'}; + +void CBC_DecodedBitStreamPaser::Initialize() {} +void CBC_DecodedBitStreamPaser::Finalize() {} +CBC_DecodedBitStreamPaser::CBC_DecodedBitStreamPaser() {} +CBC_DecodedBitStreamPaser::~CBC_DecodedBitStreamPaser() {} +CBC_CommonDecoderResult* CBC_DecodedBitStreamPaser::decode( + CFX_Int32Array& codewords, + CFX_ByteString ecLevel, + int32_t& e) { + CFX_ByteString result; + int32_t codeIndex = 1; + int32_t code = codewords.GetAt(codeIndex); + codeIndex++; + CBC_PDF417ResultMetadata* resultMetadata = new CBC_PDF417ResultMetadata; + while (codeIndex < codewords[0]) { + switch (code) { + case TEXT_COMPACTION_MODE_LATCH: + codeIndex = textCompaction(codewords, codeIndex, result); + break; + case BYTE_COMPACTION_MODE_LATCH: + codeIndex = byteCompaction(code, codewords, codeIndex, result); + break; + case NUMERIC_COMPACTION_MODE_LATCH: + codeIndex = numericCompaction(codewords, codeIndex, result, e); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + break; + case MODE_SHIFT_TO_BYTE_COMPACTION_MODE: + codeIndex = byteCompaction(code, codewords, codeIndex, result); + break; + case BYTE_COMPACTION_MODE_LATCH_6: + codeIndex = byteCompaction(code, codewords, codeIndex, result); + break; + case BEGIN_MACRO_PDF417_CONTROL_BLOCK: + codeIndex = decodeMacroBlock(codewords, codeIndex, resultMetadata, e); + if (e != BCExceptionNO) { + delete resultMetadata; + return NULL; + } + break; + default: + codeIndex--; + codeIndex = textCompaction(codewords, codeIndex, result); + break; + } + if (codeIndex < codewords.GetSize()) { + code = codewords[codeIndex++]; + } else { + e = BCExceptionFormatInstance; + delete resultMetadata; + return NULL; + } + } + if (result.GetLength() == 0) { + e = BCExceptionFormatInstance; + delete resultMetadata; + return NULL; + } + CFX_ByteArray rawBytes; + CFX_PtrArray byteSegments; + CBC_CommonDecoderResult* tempCd = new CBC_CommonDecoderResult(); + tempCd->Init(rawBytes, result, byteSegments, ecLevel, e); + if (e != BCExceptionNO) { + delete resultMetadata; + return NULL; + } + tempCd->setOther(resultMetadata); + return tempCd; +} +int32_t CBC_DecodedBitStreamPaser::decodeMacroBlock( + CFX_Int32Array& codewords, + int32_t codeIndex, + CBC_PDF417ResultMetadata* resultMetadata, + int32_t& e) { + if (codeIndex + NUMBER_OF_SEQUENCE_CODEWORDS > codewords[0]) { + e = BCExceptionFormatInstance; + return -1; + } + CFX_Int32Array segmentIndexArray; + segmentIndexArray.SetSize(NUMBER_OF_SEQUENCE_CODEWORDS); + for (int32_t i = 0; i < NUMBER_OF_SEQUENCE_CODEWORDS; i++, codeIndex++) { + segmentIndexArray.SetAt(i, codewords[codeIndex]); + } + CFX_ByteString str = + decodeBase900toBase10(segmentIndexArray, NUMBER_OF_SEQUENCE_CODEWORDS, e); + BC_EXCEPTION_CHECK_ReturnValue(e, -1); + resultMetadata->setSegmentIndex(atoi(str.GetBuffer(str.GetLength()))); + CFX_ByteString fileId; + codeIndex = textCompaction(codewords, codeIndex, fileId); + resultMetadata->setFileId(fileId); + if (codewords[codeIndex] == BEGIN_MACRO_PDF417_OPTIONAL_FIELD) { + codeIndex++; + CFX_Int32Array additionalOptionCodeWords; + additionalOptionCodeWords.SetSize(codewords[0] - codeIndex); + int32_t additionalOptionCodeWordsIndex = 0; + FX_BOOL end = FALSE; + while ((codeIndex < codewords[0]) && !end) { + int32_t code = codewords[codeIndex++]; + if (code < TEXT_COMPACTION_MODE_LATCH) { + additionalOptionCodeWords[additionalOptionCodeWordsIndex++] = code; + } else { + switch (code) { + case MACRO_PDF417_TERMINATOR: + resultMetadata->setLastSegment(TRUE); + codeIndex++; + end = TRUE; + break; + default: + e = BCExceptionFormatInstance; + return -1; + } + } + } + CFX_Int32Array array; + array.SetSize(additionalOptionCodeWordsIndex); + array.Copy(additionalOptionCodeWords); + resultMetadata->setOptionalData(array); + } else if (codewords[codeIndex] == MACRO_PDF417_TERMINATOR) { + resultMetadata->setLastSegment(TRUE); + codeIndex++; + } + return codeIndex; +} +int32_t CBC_DecodedBitStreamPaser::textCompaction(CFX_Int32Array& codewords, + int32_t codeIndex, + CFX_ByteString& result) { + CFX_Int32Array textCompactionData; + textCompactionData.SetSize((codewords[0] - codeIndex) << 1); + CFX_Int32Array byteCompactionData; + byteCompactionData.SetSize((codewords[0] - codeIndex) << 1); + int32_t index = 0; + FX_BOOL end = FALSE; + while ((codeIndex < codewords[0]) && !end) { + int32_t code = codewords[codeIndex++]; + if (code < TEXT_COMPACTION_MODE_LATCH) { + textCompactionData[index] = code / 30; + textCompactionData[index + 1] = code % 30; + index += 2; + } else { + switch (code) { + case TEXT_COMPACTION_MODE_LATCH: + textCompactionData[index++] = TEXT_COMPACTION_MODE_LATCH; + break; + case BYTE_COMPACTION_MODE_LATCH: + codeIndex--; + end = TRUE; + break; + case NUMERIC_COMPACTION_MODE_LATCH: + codeIndex--; + end = TRUE; + break; + case BEGIN_MACRO_PDF417_CONTROL_BLOCK: + codeIndex--; + end = TRUE; + break; + case BEGIN_MACRO_PDF417_OPTIONAL_FIELD: + codeIndex--; + end = TRUE; + break; + case MACRO_PDF417_TERMINATOR: + codeIndex--; + end = TRUE; + break; + case MODE_SHIFT_TO_BYTE_COMPACTION_MODE: + textCompactionData[index] = MODE_SHIFT_TO_BYTE_COMPACTION_MODE; + code = codewords[codeIndex++]; + byteCompactionData[index] = code; + index++; + break; + case BYTE_COMPACTION_MODE_LATCH_6: + codeIndex--; + end = TRUE; + break; + } + } + } + decodeTextCompaction(textCompactionData, byteCompactionData, index, result); + return codeIndex; +} +void CBC_DecodedBitStreamPaser::decodeTextCompaction( + CFX_Int32Array& textCompactionData, + CFX_Int32Array& byteCompactionData, + int32_t length, + CFX_ByteString& result) { + Mode subMode = ALPHA; + Mode priorToShiftMode = ALPHA; + int32_t i = 0; + while (i < length) { + int32_t subModeCh = textCompactionData[i]; + FX_CHAR ch = 0; + switch (subMode) { + case ALPHA: + if (subModeCh < 26) { + ch = (FX_CHAR)('A' + subModeCh); + } else { + if (subModeCh == 26) { + ch = ' '; + } else if (subModeCh == LL) { + subMode = LOWER; + } else if (subModeCh == ML) { + subMode = MIXED; + } else if (subModeCh == PS) { + priorToShiftMode = subMode; + subMode = PUNCT_SHIFT; + } else if (subModeCh == MODE_SHIFT_TO_BYTE_COMPACTION_MODE) { + result += (FX_CHAR)byteCompactionData[i]; + } else if (subModeCh == TEXT_COMPACTION_MODE_LATCH) { + subMode = ALPHA; + } + } + break; + case LOWER: + if (subModeCh < 26) { + ch = (FX_CHAR)('a' + subModeCh); + } else { + if (subModeCh == 26) { + ch = ' '; + } else if (subModeCh == AS) { + priorToShiftMode = subMode; + subMode = ALPHA_SHIFT; + } else if (subModeCh == ML) { + subMode = MIXED; + } else if (subModeCh == PS) { + priorToShiftMode = subMode; + subMode = PUNCT_SHIFT; + } else if (subModeCh == MODE_SHIFT_TO_BYTE_COMPACTION_MODE) { + result += (FX_CHAR)byteCompactionData[i]; + } else if (subModeCh == TEXT_COMPACTION_MODE_LATCH) { + subMode = ALPHA; + } + } + break; + case MIXED: + if (subModeCh < PL) { + ch = MIXED_CHARS[subModeCh]; + } else { + if (subModeCh == PL) { + subMode = PUNCT; + } else if (subModeCh == 26) { + ch = ' '; + } else if (subModeCh == LL) { + subMode = LOWER; + } else if (subModeCh == AL) { + subMode = ALPHA; + } else if (subModeCh == PS) { + priorToShiftMode = subMode; + subMode = PUNCT_SHIFT; + } else if (subModeCh == MODE_SHIFT_TO_BYTE_COMPACTION_MODE) { + result += (FX_CHAR)byteCompactionData[i]; + } else if (subModeCh == TEXT_COMPACTION_MODE_LATCH) { + subMode = ALPHA; + } + } + break; + case PUNCT: + if (subModeCh < PAL) { + ch = PUNCT_CHARS[subModeCh]; + } else { + if (subModeCh == PAL) { + subMode = ALPHA; + } else if (subModeCh == MODE_SHIFT_TO_BYTE_COMPACTION_MODE) { + result += (FX_CHAR)byteCompactionData[i]; + } else if (subModeCh == TEXT_COMPACTION_MODE_LATCH) { + subMode = ALPHA; + } + } + break; + case ALPHA_SHIFT: + subMode = priorToShiftMode; + if (subModeCh < 26) { + ch = (FX_CHAR)('A' + subModeCh); + } else { + if (subModeCh == 26) { + ch = ' '; + } else if (subModeCh == TEXT_COMPACTION_MODE_LATCH) { + subMode = ALPHA; + } + } + break; + case PUNCT_SHIFT: + subMode = priorToShiftMode; + if (subModeCh < PAL) { + ch = PUNCT_CHARS[subModeCh]; + } else { + if (subModeCh == PAL) { + subMode = ALPHA; + } else if (subModeCh == MODE_SHIFT_TO_BYTE_COMPACTION_MODE) { + result += (FX_CHAR)byteCompactionData[i]; + } else if (subModeCh == TEXT_COMPACTION_MODE_LATCH) { + subMode = ALPHA; + } + } + break; + } + if (ch != 0) { + result += ch; + } + i++; + } +} +int32_t CBC_DecodedBitStreamPaser::byteCompaction(int32_t mode, + CFX_Int32Array& codewords, + int32_t codeIndex, + CFX_ByteString& result) { + if (mode == BYTE_COMPACTION_MODE_LATCH) { + int32_t count = 0; + int64_t value = 0; + FX_WORD* decodedData = FX_Alloc(FX_WORD, 6); + CFX_Int32Array byteCompactedCodewords; + byteCompactedCodewords.SetSize(6); + FX_BOOL end = FALSE; + int32_t nextCode = codewords[codeIndex++]; + while ((codeIndex < codewords[0]) && !end) { + byteCompactedCodewords[count++] = nextCode; + value = 900 * value + nextCode; + nextCode = codewords[codeIndex++]; + if (nextCode == TEXT_COMPACTION_MODE_LATCH || + nextCode == BYTE_COMPACTION_MODE_LATCH || + nextCode == NUMERIC_COMPACTION_MODE_LATCH || + nextCode == BYTE_COMPACTION_MODE_LATCH_6 || + nextCode == BEGIN_MACRO_PDF417_CONTROL_BLOCK || + nextCode == BEGIN_MACRO_PDF417_OPTIONAL_FIELD || + nextCode == MACRO_PDF417_TERMINATOR) { + codeIndex--; + end = TRUE; + } else { + if ((count % 5 == 0) && (count > 0)) { + int32_t j = 0; + for (; j < 6; ++j) { + decodedData[5 - j] = (FX_WORD)(value % 256); + value >>= 8; + } + for (j = 0; j < 6; ++j) { + result += (FX_CHAR)decodedData[j]; + } + count = 0; + } + } + } + FX_Free(decodedData); + if (codeIndex == codewords[0] && nextCode < TEXT_COMPACTION_MODE_LATCH) { + byteCompactedCodewords[count++] = nextCode; + } + for (int32_t i = 0; i < count; i++) { + result += (FX_CHAR)(FX_WORD)byteCompactedCodewords[i]; + } + } else if (mode == BYTE_COMPACTION_MODE_LATCH_6) { + int32_t count = 0; + int64_t value = 0; + FX_BOOL end = FALSE; + while (codeIndex < codewords[0] && !end) { + int32_t code = codewords[codeIndex++]; + if (code < TEXT_COMPACTION_MODE_LATCH) { + count++; + value = 900 * value + code; + } else { + if (code == TEXT_COMPACTION_MODE_LATCH || + code == BYTE_COMPACTION_MODE_LATCH || + code == NUMERIC_COMPACTION_MODE_LATCH || + code == BYTE_COMPACTION_MODE_LATCH_6 || + code == BEGIN_MACRO_PDF417_CONTROL_BLOCK || + code == BEGIN_MACRO_PDF417_OPTIONAL_FIELD || + code == MACRO_PDF417_TERMINATOR) { + codeIndex--; + end = TRUE; + } + } + if ((count % 5 == 0) && (count > 0)) { + FX_WORD* decodedData = FX_Alloc(FX_WORD, 6); + int32_t j = 0; + for (; j < 6; ++j) { + decodedData[5 - j] = (FX_WORD)(value & 0xFF); + value >>= 8; + } + for (j = 0; j < 6; ++j) { + result += (FX_CHAR)decodedData[j]; + } + count = 0; + FX_Free(decodedData); + } + } + } + return codeIndex; +} +int32_t CBC_DecodedBitStreamPaser::numericCompaction(CFX_Int32Array& codewords, + int32_t codeIndex, + CFX_ByteString& result, + int32_t& e) { + int32_t count = 0; + FX_BOOL end = FALSE; + CFX_Int32Array numericCodewords; + numericCodewords.SetSize(MAX_NUMERIC_CODEWORDS); + while (codeIndex < codewords[0] && !end) { + int32_t code = codewords[codeIndex++]; + if (codeIndex == codewords[0]) { + end = TRUE; + } + if (code < TEXT_COMPACTION_MODE_LATCH) { + numericCodewords[count] = code; + count++; + } else { + if (code == TEXT_COMPACTION_MODE_LATCH || + code == BYTE_COMPACTION_MODE_LATCH || + code == BYTE_COMPACTION_MODE_LATCH_6 || + code == BEGIN_MACRO_PDF417_CONTROL_BLOCK || + code == BEGIN_MACRO_PDF417_OPTIONAL_FIELD || + code == MACRO_PDF417_TERMINATOR) { + codeIndex--; + end = TRUE; + } + } + if (count % MAX_NUMERIC_CODEWORDS == 0 || + code == NUMERIC_COMPACTION_MODE_LATCH || end) { + CFX_ByteString s = decodeBase900toBase10(numericCodewords, count, e); + BC_EXCEPTION_CHECK_ReturnValue(e, -1); + result += s; + count = 0; + } + } + return codeIndex; +} +CFX_ByteString CBC_DecodedBitStreamPaser::decodeBase900toBase10( + CFX_Int32Array& codewords, + int32_t count, + int32_t& e) { + BigInteger result = 0; + BigInteger nineHundred(900); + for (int32_t i = 0; i < count; i++) { + result = result * nineHundred + BigInteger(codewords[i]); + } + CFX_ByteString resultString(bigIntegerToString(result).c_str()); + if (resultString.GetAt(0) != '1') { + e = BCExceptionFormatInstance; + return ' '; + } + return resultString.Mid(1, resultString.GetLength() - 1); +} diff --git a/xfa/fxbarcode/pdf417/BC_PDF417DecodedBitStreamParser.h b/xfa/fxbarcode/pdf417/BC_PDF417DecodedBitStreamParser.h new file mode 100644 index 0000000000..747a4ceb5d --- /dev/null +++ b/xfa/fxbarcode/pdf417/BC_PDF417DecodedBitStreamParser.h @@ -0,0 +1,63 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef XFA_FXBARCODE_PDF417_BC_PDF417DECODEDBITSTREAMPARSER_H_ +#define XFA_FXBARCODE_PDF417_BC_PDF417DECODEDBITSTREAMPARSER_H_ + +#include "core/include/fxcrt/fx_basic.h" +#include "core/include/fxcrt/fx_string.h" + +class CBC_CommonDecoderResult; +class CBC_PDF417ResultMetadata; + +class CBC_DecodedBitStreamPaser { + public: + CBC_DecodedBitStreamPaser(); + virtual ~CBC_DecodedBitStreamPaser(); + static void Initialize(); + static void Finalize(); + static CBC_CommonDecoderResult* decode(CFX_Int32Array& codewords, + CFX_ByteString ecLevel, + int32_t& e); + + private: + enum Mode { ALPHA, LOWER, MIXED, PUNCT, ALPHA_SHIFT, PUNCT_SHIFT }; + static int32_t MAX_NUMERIC_CODEWORDS; + static int32_t PL; + static int32_t LL; + static int32_t AS; + static int32_t ML; + static int32_t AL; + static int32_t PS; + static int32_t PAL; + static FX_CHAR PUNCT_CHARS[29]; + static FX_CHAR MIXED_CHARS[30]; + static int32_t NUMBER_OF_SEQUENCE_CODEWORDS; + static int32_t decodeMacroBlock(CFX_Int32Array& codewords, + int32_t codeIndex, + CBC_PDF417ResultMetadata* resultMetadata, + int32_t& e); + static int32_t textCompaction(CFX_Int32Array& codewords, + int32_t codeIndex, + CFX_ByteString& result); + static void decodeTextCompaction(CFX_Int32Array& textCompactionData, + CFX_Int32Array& byteCompactionData, + int32_t length, + CFX_ByteString& result); + static int32_t byteCompaction(int32_t mode, + CFX_Int32Array& codewords, + int32_t codeIndex, + CFX_ByteString& result); + static int32_t numericCompaction(CFX_Int32Array& codewords, + int32_t codeIndex, + CFX_ByteString& result, + int32_t& e); + static CFX_ByteString decodeBase900toBase10(CFX_Int32Array& codewords, + int32_t count, + int32_t& e); +}; + +#endif // XFA_FXBARCODE_PDF417_BC_PDF417DECODEDBITSTREAMPARSER_H_ diff --git a/xfa/fxbarcode/pdf417/BC_PDF417DetectionResult.cpp b/xfa/fxbarcode/pdf417/BC_PDF417DetectionResult.cpp new file mode 100644 index 0000000000..fa278bdea9 --- /dev/null +++ b/xfa/fxbarcode/pdf417/BC_PDF417DetectionResult.cpp @@ -0,0 +1,339 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com +// Original code is licensed as follows: +/* + * Copyright 2013 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "xfa/fxbarcode/pdf417/BC_PDF417BarcodeMetadata.h" +#include "xfa/fxbarcode/pdf417/BC_PDF417BoundingBox.h" +#include "xfa/fxbarcode/pdf417/BC_PDF417Codeword.h" +#include "xfa/fxbarcode/pdf417/BC_PDF417Common.h" +#include "xfa/fxbarcode/pdf417/BC_PDF417DetectionResult.h" +#include "xfa/fxbarcode/pdf417/BC_PDF417DetectionResultColumn.h" +#include "xfa/fxbarcode/pdf417/BC_PDF417DetectionResultRowIndicatorColumn.h" + +int32_t CBC_DetectionResult::ADJUST_ROW_NUMBER_SKIP = 2; + +CBC_DetectionResult::CBC_DetectionResult(CBC_BarcodeMetadata* barcodeMetadata, + CBC_BoundingBox* boundingBox) { + m_barcodeMetadata = barcodeMetadata; + m_barcodeColumnCount = barcodeMetadata->getColumnCount(); + m_boundingBox = boundingBox; + m_detectionResultColumns.SetSize(m_barcodeColumnCount + 2); + for (int32_t i = 0; i < m_barcodeColumnCount + 2; i++) { + m_detectionResultColumns[i] = NULL; + } +} +CBC_DetectionResult::~CBC_DetectionResult() { + delete m_boundingBox; + delete m_barcodeMetadata; + m_detectionResultColumns.RemoveAll(); +} +CFX_PtrArray& CBC_DetectionResult::getDetectionResultColumns() { + adjustIndicatorColumnRowNumbers( + (CBC_DetectionResultColumn*)m_detectionResultColumns.GetAt(0)); + adjustIndicatorColumnRowNumbers( + (CBC_DetectionResultColumn*)m_detectionResultColumns.GetAt( + m_barcodeColumnCount + 1)); + int32_t unadjustedCodewordCount = CBC_PDF417Common::MAX_CODEWORDS_IN_BARCODE; + int32_t previousUnadjustedCount; + do { + previousUnadjustedCount = unadjustedCodewordCount; + unadjustedCodewordCount = adjustRowNumbers(); + } while (unadjustedCodewordCount > 0 && + unadjustedCodewordCount < previousUnadjustedCount); + return m_detectionResultColumns; +} +void CBC_DetectionResult::setBoundingBox(CBC_BoundingBox* boundingBox) { + m_boundingBox = boundingBox; +} +CBC_BoundingBox* CBC_DetectionResult::getBoundingBox() { + return m_boundingBox; +} +void CBC_DetectionResult::setDetectionResultColumn( + int32_t barcodeColumn, + CBC_DetectionResultColumn* detectionResultColumn) { + m_detectionResultColumns[barcodeColumn] = detectionResultColumn; +} +CBC_DetectionResultColumn* CBC_DetectionResult::getDetectionResultColumn( + int32_t barcodeColumn) { + return (CBC_DetectionResultColumn*)m_detectionResultColumns[barcodeColumn]; +} +CFX_ByteString CBC_DetectionResult::toString() { + CBC_DetectionResultColumn* rowIndicatorColumn = + (CBC_DetectionResultColumn*)m_detectionResultColumns[0]; + if (rowIndicatorColumn == NULL) { + rowIndicatorColumn = (CBC_DetectionResultColumn*) + m_detectionResultColumns[m_barcodeColumnCount + 1]; + } + CFX_ByteString result; + for (int32_t codewordsRow = 0; + codewordsRow < rowIndicatorColumn->getCodewords()->GetSize(); + codewordsRow++) { + result += (FX_CHAR)codewordsRow; + for (int32_t barcodeColumn = 0; barcodeColumn < m_barcodeColumnCount + 2; + barcodeColumn++) { + if (m_detectionResultColumns[barcodeColumn] == NULL) { + result += " | "; + continue; + } + CBC_Codeword* codeword = + (CBC_Codeword*)((CBC_DetectionResultColumn*) + m_detectionResultColumns[barcodeColumn]) + ->getCodewords() + ->GetAt(codewordsRow); + if (codeword == NULL) { + result += " | "; + continue; + } + result += codeword->getRowNumber(); + result += codeword->getValue(); + } + } + return result; +} +void CBC_DetectionResult::adjustIndicatorColumnRowNumbers( + CBC_DetectionResultColumn* detectionResultColumn) { + if (detectionResultColumn) { + ((CBC_DetectionResultRowIndicatorColumn*)detectionResultColumn) + ->adjustCompleteIndicatorColumnRowNumbers(*m_barcodeMetadata); + } +} +int32_t CBC_DetectionResult::adjustRowNumbers() { + int32_t unadjustedCount = adjustRowNumbersByRow(); + if (unadjustedCount == 0) { + return 0; + } + for (int32_t barcodeColumn = 1; barcodeColumn < m_barcodeColumnCount + 1; + barcodeColumn++) { + CFX_PtrArray* codewords = + ((CBC_DetectionResultColumn*)m_detectionResultColumns[barcodeColumn]) + ->getCodewords(); + for (int32_t codewordsRow = 0; codewordsRow < codewords->GetSize(); + codewordsRow++) { + if (codewords->GetAt(codewordsRow) == NULL) { + continue; + } + if (!((CBC_Codeword*)codewords->GetAt(codewordsRow)) + ->hasValidRowNumber()) { + adjustRowNumbers(barcodeColumn, codewordsRow, codewords); + } + } + } + return unadjustedCount; +} +int32_t CBC_DetectionResult::adjustRowNumbersByRow() { + adjustRowNumbersFromBothRI(); + int32_t unadjustedCount = adjustRowNumbersFromLRI(); + return unadjustedCount + adjustRowNumbersFromRRI(); +} +int32_t CBC_DetectionResult::adjustRowNumbersFromBothRI() { + if (m_detectionResultColumns[0] == NULL || + m_detectionResultColumns[m_barcodeColumnCount + 1] == NULL) { + return 0; + } + CFX_PtrArray* LRIcodewords = + ((CBC_DetectionResultColumn*)m_detectionResultColumns[0])->getCodewords(); + CFX_PtrArray* RRIcodewords = + ((CBC_DetectionResultColumn*) + m_detectionResultColumns[m_barcodeColumnCount + 1]) + ->getCodewords(); + for (int32_t codewordsRow = 0; codewordsRow < LRIcodewords->GetSize(); + codewordsRow++) { + if (LRIcodewords->GetAt(codewordsRow) && + RRIcodewords->GetAt(codewordsRow) && + ((CBC_Codeword*)LRIcodewords->GetAt(codewordsRow))->getRowNumber() == + ((CBC_Codeword*)RRIcodewords->GetAt(codewordsRow)) + ->getRowNumber()) { + for (int32_t barcodeColumn = 1; barcodeColumn <= m_barcodeColumnCount; + barcodeColumn++) { + CBC_Codeword* codeword = + (CBC_Codeword*)((CBC_DetectionResultColumn*) + m_detectionResultColumns[barcodeColumn]) + ->getCodewords() + ->GetAt(codewordsRow); + if (codeword == NULL) { + continue; + } + codeword->setRowNumber( + ((CBC_Codeword*)LRIcodewords->GetAt(codewordsRow))->getRowNumber()); + if (!codeword->hasValidRowNumber()) { + ((CBC_DetectionResultColumn*)m_detectionResultColumns[barcodeColumn]) + ->getCodewords() + ->SetAt(codewordsRow, NULL); + } + } + } + } + return 0; +} +int32_t CBC_DetectionResult::adjustRowNumbersFromRRI() { + if (m_detectionResultColumns[m_barcodeColumnCount + 1] == NULL) { + return 0; + } + int32_t unadjustedCount = 0; + CFX_PtrArray* codewords = + ((CBC_DetectionResultColumn*)m_detectionResultColumns.GetAt( + m_barcodeColumnCount + 1)) + ->getCodewords(); + for (int32_t codewordsRow = 0; codewordsRow < codewords->GetSize(); + codewordsRow++) { + if (codewords->GetAt(codewordsRow) == NULL) { + continue; + } + int32_t rowIndicatorRowNumber = + ((CBC_Codeword*)codewords->GetAt(codewordsRow))->getRowNumber(); + int32_t invalidRowCounts = 0; + for (int32_t barcodeColumn = m_barcodeColumnCount + 1; + barcodeColumn > 0 && invalidRowCounts < ADJUST_ROW_NUMBER_SKIP; + barcodeColumn--) { + CBC_Codeword* codeword = + (CBC_Codeword*)((CBC_DetectionResultColumn*) + m_detectionResultColumns.GetAt(barcodeColumn)) + ->getCodewords() + ->GetAt(codewordsRow); + if (codeword) { + invalidRowCounts = adjustRowNumberIfValid(rowIndicatorRowNumber, + invalidRowCounts, codeword); + if (!codeword->hasValidRowNumber()) { + unadjustedCount++; + } + } + } + } + return unadjustedCount; +} +int32_t CBC_DetectionResult::adjustRowNumbersFromLRI() { + if (m_detectionResultColumns[0] == NULL) { + return 0; + } + int32_t unadjustedCount = 0; + CFX_PtrArray* codewords = + ((CBC_DetectionResultColumn*)m_detectionResultColumns.GetAt(0)) + ->getCodewords(); + for (int32_t codewordsRow = 0; codewordsRow < codewords->GetSize(); + codewordsRow++) { + if (codewords->GetAt(codewordsRow) == NULL) { + continue; + } + int32_t rowIndicatorRowNumber = + ((CBC_Codeword*)codewords->GetAt(codewordsRow))->getRowNumber(); + int32_t invalidRowCounts = 0; + for (int32_t barcodeColumn = 1; barcodeColumn < m_barcodeColumnCount + 1 && + invalidRowCounts < ADJUST_ROW_NUMBER_SKIP; + barcodeColumn++) { + CBC_Codeword* codeword = + (CBC_Codeword*)((CBC_DetectionResultColumn*) + m_detectionResultColumns[barcodeColumn]) + ->getCodewords() + ->GetAt(codewordsRow); + if (codeword) { + invalidRowCounts = adjustRowNumberIfValid(rowIndicatorRowNumber, + invalidRowCounts, codeword); + if (!codeword->hasValidRowNumber()) { + unadjustedCount++; + } + } + } + } + return unadjustedCount; +} +int32_t CBC_DetectionResult::adjustRowNumberIfValid( + int32_t rowIndicatorRowNumber, + int32_t invalidRowCounts, + CBC_Codeword* codeword) { + if (codeword == NULL) { + return invalidRowCounts; + } + if (!codeword->hasValidRowNumber()) { + if (codeword->isValidRowNumber(rowIndicatorRowNumber)) { + codeword->setRowNumber(rowIndicatorRowNumber); + invalidRowCounts = 0; + } else { + ++invalidRowCounts; + } + } + return invalidRowCounts; +} +void CBC_DetectionResult::adjustRowNumbers(int32_t barcodeColumn, + int32_t codewordsRow, + CFX_PtrArray* codewords) { + CBC_Codeword* codeword = (CBC_Codeword*)codewords->GetAt(codewordsRow); + CFX_PtrArray* previousColumnCodewords = + ((CBC_DetectionResultColumn*)m_detectionResultColumns.GetAt( + barcodeColumn - 1)) + ->getCodewords(); + CFX_PtrArray* nextColumnCodewords = previousColumnCodewords; + if (m_detectionResultColumns[barcodeColumn + 1]) { + nextColumnCodewords = ((CBC_DetectionResultColumn*) + m_detectionResultColumns[barcodeColumn + 1]) + ->getCodewords(); + } + CFX_PtrArray otherCodewords; + otherCodewords.SetSize(14); + otherCodewords[2] = previousColumnCodewords->GetAt(codewordsRow); + otherCodewords[3] = nextColumnCodewords->GetAt(codewordsRow); + if (codewordsRow > 0) { + otherCodewords[0] = codewords->GetAt(codewordsRow - 1); + otherCodewords[4] = previousColumnCodewords->GetAt(codewordsRow - 1); + otherCodewords[5] = nextColumnCodewords->GetAt(codewordsRow - 1); + } + if (codewordsRow > 1) { + otherCodewords[8] = codewords->GetAt(codewordsRow - 2); + otherCodewords[10] = previousColumnCodewords->GetAt(codewordsRow - 2); + otherCodewords[11] = nextColumnCodewords->GetAt(codewordsRow - 2); + } + if (codewordsRow < codewords->GetSize() - 1) { + otherCodewords[1] = codewords->GetAt(codewordsRow + 1); + otherCodewords[6] = previousColumnCodewords->GetAt(codewordsRow + 1); + otherCodewords[7] = nextColumnCodewords->GetAt(codewordsRow + 1); + } + if (codewordsRow < codewords->GetSize() - 2) { + otherCodewords[9] = codewords->GetAt(codewordsRow + 2); + otherCodewords[12] = previousColumnCodewords->GetAt(codewordsRow + 2); + otherCodewords[13] = nextColumnCodewords->GetAt(codewordsRow + 2); + } + for (int32_t i = 0; i < otherCodewords.GetSize(); i++) { + CBC_Codeword* otherCodeword = (CBC_Codeword*)otherCodewords.GetAt(i); + if (adjustRowNumber(codeword, otherCodeword)) { + return; + } + } +} +FX_BOOL CBC_DetectionResult::adjustRowNumber(CBC_Codeword* codeword, + CBC_Codeword* otherCodeword) { + if (otherCodeword == NULL) { + return FALSE; + } + if (otherCodeword->hasValidRowNumber() && + otherCodeword->getBucket() == codeword->getBucket()) { + codeword->setRowNumber(otherCodeword->getRowNumber()); + return TRUE; + } + return FALSE; +} +int32_t CBC_DetectionResult::getBarcodeColumnCount() { + return m_barcodeColumnCount; +} +int32_t CBC_DetectionResult::getBarcodeRowCount() { + return m_barcodeMetadata->getRowCount(); +} +int32_t CBC_DetectionResult::getBarcodeECLevel() { + return m_barcodeMetadata->getErrorCorrectionLevel(); +} diff --git a/xfa/fxbarcode/pdf417/BC_PDF417DetectionResult.h b/xfa/fxbarcode/pdf417/BC_PDF417DetectionResult.h new file mode 100644 index 0000000000..8b7f91bfcd --- /dev/null +++ b/xfa/fxbarcode/pdf417/BC_PDF417DetectionResult.h @@ -0,0 +1,57 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef XFA_FXBARCODE_PDF417_BC_PDF417DETECTIONRESULT_H_ +#define XFA_FXBARCODE_PDF417_BC_PDF417DETECTIONRESULT_H_ + +class CBC_BarcodeMetadata; +class CBC_BoundingBox; +class CBC_Codeword; +class CBC_DetectionResultColumn; +class CBC_DetectionResult { + public: + CBC_DetectionResult(CBC_BarcodeMetadata* barcodeMetadata, + CBC_BoundingBox* boundingBox); + virtual ~CBC_DetectionResult(); + CFX_PtrArray& getDetectionResultColumns(); + void setBoundingBox(CBC_BoundingBox* boundingBox); + CBC_BoundingBox* getBoundingBox(); + void setDetectionResultColumn( + int32_t barcodeColumn, + CBC_DetectionResultColumn* detectionResultColumn); + CBC_DetectionResultColumn* getDetectionResultColumn(int32_t barcodeColumn); + CFX_ByteString toString(); + + int32_t getBarcodeColumnCount(); + int32_t getBarcodeRowCount(); + int32_t getBarcodeECLevel(); + + private: + static int32_t ADJUST_ROW_NUMBER_SKIP; + CBC_BarcodeMetadata* m_barcodeMetadata; + CFX_PtrArray m_detectionResultColumns; + CBC_BoundingBox* m_boundingBox; + int32_t m_barcodeColumnCount; + + private: + void adjustIndicatorColumnRowNumbers( + CBC_DetectionResultColumn* detectionResultColumn); + int32_t adjustRowNumbers(); + int32_t adjustRowNumbersByRow(); + int32_t adjustRowNumbersFromBothRI(); + int32_t adjustRowNumbersFromRRI(); + int32_t adjustRowNumbersFromLRI(); + static int32_t adjustRowNumberIfValid(int32_t rowIndicatorRowNumber, + int32_t invalidRowCounts, + CBC_Codeword* codeword); + void adjustRowNumbers(int32_t barcodeColumn, + int32_t codewordsRow, + CFX_PtrArray* codewords); + static FX_BOOL adjustRowNumber(CBC_Codeword* codeword, + CBC_Codeword* otherCodeword); +}; + +#endif // XFA_FXBARCODE_PDF417_BC_PDF417DETECTIONRESULT_H_ diff --git a/xfa/fxbarcode/pdf417/BC_PDF417DetectionResultColumn.cpp b/xfa/fxbarcode/pdf417/BC_PDF417DetectionResultColumn.cpp new file mode 100644 index 0000000000..24d81070f3 --- /dev/null +++ b/xfa/fxbarcode/pdf417/BC_PDF417DetectionResultColumn.cpp @@ -0,0 +1,101 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com +// Original code is licensed as follows: +/* + * Copyright 2013 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "xfa/fxbarcode/pdf417/BC_PDF417BoundingBox.h" +#include "xfa/fxbarcode/pdf417/BC_PDF417Codeword.h" +#include "xfa/fxbarcode/pdf417/BC_PDF417DetectionResultColumn.h" + +int32_t CBC_DetectionResultColumn::MAX_NEARBY_DISTANCE = 5; + +CBC_DetectionResultColumn::CBC_DetectionResultColumn( + CBC_BoundingBox* boundingBox) { + m_boundingBox = boundingBox; + m_codewords = new CFX_PtrArray; + m_codewords->SetSize(boundingBox->getMaxY() - boundingBox->getMinY() + 1); +} +CBC_DetectionResultColumn::~CBC_DetectionResultColumn() { + for (int32_t i = 0; i < m_codewords->GetSize(); i++) { + delete (CBC_Codeword*)m_codewords->GetAt(i); + } + m_codewords->RemoveAll(); + delete m_codewords; +} +CBC_Codeword* CBC_DetectionResultColumn::getCodewordNearby(int32_t imageRow) { + CBC_Codeword* codeword = getCodeword(imageRow); + if (codeword) { + return codeword; + } + for (int32_t i = 1; i < MAX_NEARBY_DISTANCE; i++) { + int32_t nearImageRow = imageRowToCodewordIndex(imageRow) - i; + if (nearImageRow >= 0) { + codeword = (CBC_Codeword*)m_codewords->GetAt(nearImageRow); + if (codeword) { + return codeword; + } + } + nearImageRow = imageRowToCodewordIndex(imageRow) + i; + if (nearImageRow < m_codewords->GetSize()) { + codeword = (CBC_Codeword*)m_codewords->GetAt(nearImageRow); + if (codeword) { + return codeword; + } + } + } + return NULL; +} +int32_t CBC_DetectionResultColumn::imageRowToCodewordIndex(int32_t imageRow) { + return imageRow - m_boundingBox->getMinY(); +} +int32_t CBC_DetectionResultColumn::codewordIndexToImageRow( + int32_t codewordIndex) { + return m_boundingBox->getMinY() + codewordIndex; +} +void CBC_DetectionResultColumn::setCodeword(int32_t imageRow, + CBC_Codeword* codeword) { + m_codewords->SetAt(imageRowToCodewordIndex(imageRow), codeword); +} +CBC_Codeword* CBC_DetectionResultColumn::getCodeword(int32_t imageRow) { + return (CBC_Codeword*)m_codewords->GetAt(imageRowToCodewordIndex(imageRow)); +} +CBC_BoundingBox* CBC_DetectionResultColumn::getBoundingBox() { + return m_boundingBox; +} +CFX_PtrArray* CBC_DetectionResultColumn::getCodewords() { + return m_codewords; +} +CFX_ByteString CBC_DetectionResultColumn::toString() { + CFX_ByteString result; + int32_t row = 0; + for (int32_t i = 0; i < m_codewords->GetSize(); i++) { + CBC_Codeword* codeword = (CBC_Codeword*)m_codewords->GetAt(i); + if (codeword == NULL) { + result += (FX_CHAR)row; + row++; + continue; + } + result += (FX_CHAR)row; + result += codeword->getRowNumber(); + result += codeword->getValue(); + row++; + } + return result; +} diff --git a/xfa/fxbarcode/pdf417/BC_PDF417DetectionResultColumn.h b/xfa/fxbarcode/pdf417/BC_PDF417DetectionResultColumn.h new file mode 100644 index 0000000000..ebe01a2a0c --- /dev/null +++ b/xfa/fxbarcode/pdf417/BC_PDF417DetectionResultColumn.h @@ -0,0 +1,33 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef XFA_FXBARCODE_PDF417_BC_PDF417DETECTIONRESULTCOLUMN_H_ +#define XFA_FXBARCODE_PDF417_BC_PDF417DETECTIONRESULTCOLUMN_H_ + +class CBC_Codeword; +class CBC_BoundingBox; +class CBC_DetectionResultColumn { + public: + CBC_DetectionResultColumn(CBC_BoundingBox* boundingBox); + virtual ~CBC_DetectionResultColumn(); + CBC_Codeword* getCodewordNearby(int32_t imageRow); + int32_t imageRowToCodewordIndex(int32_t imageRow); + int32_t codewordIndexToImageRow(int32_t codewordIndex); + void setCodeword(int32_t imageRow, CBC_Codeword* codeword); + CBC_Codeword* getCodeword(int32_t imageRow); + CBC_BoundingBox* getBoundingBox(); + CFX_PtrArray* getCodewords(); + CFX_ByteString toString(); + + public: + CBC_BoundingBox* m_boundingBox; + CFX_PtrArray* m_codewords; + + private: + static int32_t MAX_NEARBY_DISTANCE; +}; + +#endif // XFA_FXBARCODE_PDF417_BC_PDF417DETECTIONRESULTCOLUMN_H_ diff --git a/xfa/fxbarcode/pdf417/BC_PDF417DetectionResultRowIndicatorColumn.cpp b/xfa/fxbarcode/pdf417/BC_PDF417DetectionResultRowIndicatorColumn.cpp new file mode 100644 index 0000000000..22fd25df8b --- /dev/null +++ b/xfa/fxbarcode/pdf417/BC_PDF417DetectionResultRowIndicatorColumn.cpp @@ -0,0 +1,267 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com +// Original code is licensed as follows: +/* + * Copyright 2013 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "core/include/fxcrt/fx_basic.h" +#include "xfa/fxbarcode/BC_ResultPoint.h" +#include "xfa/fxbarcode/pdf417/BC_PDF417BarcodeMetadata.h" +#include "xfa/fxbarcode/pdf417/BC_PDF417BarcodeValue.h" +#include "xfa/fxbarcode/pdf417/BC_PDF417BoundingBox.h" +#include "xfa/fxbarcode/pdf417/BC_PDF417Codeword.h" +#include "xfa/fxbarcode/pdf417/BC_PDF417Common.h" +#include "xfa/fxbarcode/pdf417/BC_PDF417DetectionResultColumn.h" +#include "xfa/fxbarcode/pdf417/BC_PDF417DetectionResultRowIndicatorColumn.h" +#include "xfa/fxbarcode/utils.h" + +CBC_DetectionResultRowIndicatorColumn::CBC_DetectionResultRowIndicatorColumn( + CBC_BoundingBox* boundingBox, + FX_BOOL isLeft) + : CBC_DetectionResultColumn(boundingBox) { + m_isLeft = isLeft; +} +CBC_DetectionResultRowIndicatorColumn:: + ~CBC_DetectionResultRowIndicatorColumn() {} +void CBC_DetectionResultRowIndicatorColumn::setRowNumbers() { + for (int32_t i = 0; i < m_codewords->GetSize(); i++) { + CBC_Codeword* codeword = (CBC_Codeword*)m_codewords->GetAt(i); + if (codeword) { + codeword->setRowNumberAsRowIndicatorColumn(); + } + } +} +int32_t +CBC_DetectionResultRowIndicatorColumn::adjustCompleteIndicatorColumnRowNumbers( + CBC_BarcodeMetadata barcodeMetadata) { + CFX_PtrArray* codewords = getCodewords(); + setRowNumbers(); + removeIncorrectCodewords(codewords, barcodeMetadata); + CBC_BoundingBox* boundingBox = getBoundingBox(); + CBC_ResultPoint* top = + m_isLeft ? boundingBox->getTopLeft() : boundingBox->getTopRight(); + CBC_ResultPoint* bottom = + m_isLeft ? boundingBox->getBottomLeft() : boundingBox->getBottomRight(); + int32_t firstRow = imageRowToCodewordIndex((int32_t)top->GetY()); + int32_t lastRow = imageRowToCodewordIndex((int32_t)bottom->GetY()); + FX_FLOAT averageRowHeight = + (lastRow - firstRow) / (FX_FLOAT)barcodeMetadata.getRowCount(); + int32_t barcodeRow = -1; + int32_t maxRowHeight = 1; + int32_t currentRowHeight = 0; + for (int32_t codewordsRow = firstRow; codewordsRow < lastRow; + codewordsRow++) { + if (codewords->GetAt(codewordsRow) == NULL) { + continue; + } + CBC_Codeword* codeword = (CBC_Codeword*)codewords->GetAt(codewordsRow); + int32_t rowDifference = codeword->getRowNumber() - barcodeRow; + if (rowDifference == 0) { + currentRowHeight++; + } else if (rowDifference == 1) { + maxRowHeight = + maxRowHeight > currentRowHeight ? maxRowHeight : currentRowHeight; + currentRowHeight = 1; + barcodeRow = codeword->getRowNumber(); + } else if (rowDifference < 0) { + codewords->SetAt(codewordsRow, NULL); + } else if (codeword->getRowNumber() >= barcodeMetadata.getRowCount()) { + codewords->SetAt(codewordsRow, NULL); + } else if (rowDifference > codewordsRow) { + codewords->SetAt(codewordsRow, NULL); + } else { + int32_t checkedRows; + if (maxRowHeight > 2) { + checkedRows = (maxRowHeight - 2) * rowDifference; + } else { + checkedRows = rowDifference; + } + FX_BOOL closePreviousCodewordFound = checkedRows >= codewordsRow; + for (int32_t i = 1; i <= checkedRows && !closePreviousCodewordFound; + i++) { + closePreviousCodewordFound = codewords->GetAt(codewordsRow - i) != NULL; + } + if (closePreviousCodewordFound) { + codewords->SetAt(codewordsRow, NULL); + } else { + barcodeRow = codeword->getRowNumber(); + currentRowHeight = 1; + } + } + } + return (int32_t)(averageRowHeight + 0.5); +} +CFX_Int32Array* CBC_DetectionResultRowIndicatorColumn::getRowHeights( + int32_t& e) { + CBC_BarcodeMetadata* barcodeMetadata = getBarcodeMetadata(); + if (barcodeMetadata == NULL) { + e = BCExceptionCannotMetadata; + return NULL; + } + adjustIncompleteIndicatorColumnRowNumbers(*barcodeMetadata); + CFX_Int32Array* result = new CFX_Int32Array; + result->SetSize(barcodeMetadata->getRowCount()); + for (int32_t i = 0; i < getCodewords()->GetSize(); i++) { + CBC_Codeword* codeword = (CBC_Codeword*)getCodewords()->GetAt(i); + if (codeword) { + result->SetAt(codeword->getRowNumber(), + result->GetAt(codeword->getRowNumber()) + 1); + } + } + return result; +} +int32_t CBC_DetectionResultRowIndicatorColumn:: + adjustIncompleteIndicatorColumnRowNumbers( + CBC_BarcodeMetadata barcodeMetadata) { + CBC_BoundingBox* boundingBox = getBoundingBox(); + CBC_ResultPoint* top = + m_isLeft ? boundingBox->getTopLeft() : boundingBox->getTopRight(); + CBC_ResultPoint* bottom = + m_isLeft ? boundingBox->getBottomLeft() : boundingBox->getBottomRight(); + int32_t firstRow = imageRowToCodewordIndex((int32_t)top->GetY()); + int32_t lastRow = imageRowToCodewordIndex((int32_t)bottom->GetY()); + FX_FLOAT averageRowHeight = + (lastRow - firstRow) / (FX_FLOAT)barcodeMetadata.getRowCount(); + CFX_PtrArray* codewords = getCodewords(); + int32_t barcodeRow = -1; + int32_t maxRowHeight = 1; + int32_t currentRowHeight = 0; + for (int32_t codewordsRow = firstRow; codewordsRow < lastRow; + codewordsRow++) { + if (codewords->GetAt(codewordsRow) == NULL) { + continue; + } + CBC_Codeword* codeword = (CBC_Codeword*)codewords->GetAt(codewordsRow); + codeword->setRowNumberAsRowIndicatorColumn(); + int32_t rowDifference = codeword->getRowNumber() - barcodeRow; + if (rowDifference == 0) { + currentRowHeight++; + } else if (rowDifference == 1) { + maxRowHeight = + maxRowHeight > currentRowHeight ? maxRowHeight : currentRowHeight; + currentRowHeight = 1; + barcodeRow = codeword->getRowNumber(); + } else if (codeword->getRowNumber() >= barcodeMetadata.getRowCount()) { + codewords->SetAt(codewordsRow, NULL); + } else { + barcodeRow = codeword->getRowNumber(); + currentRowHeight = 1; + } + } + return (int32_t)(averageRowHeight + 0.5); +} +CBC_BarcodeMetadata* +CBC_DetectionResultRowIndicatorColumn::getBarcodeMetadata() { + CFX_PtrArray* codewords = getCodewords(); + CBC_BarcodeValue barcodeColumnCount; + CBC_BarcodeValue barcodeRowCountUpperPart; + CBC_BarcodeValue barcodeRowCountLowerPart; + CBC_BarcodeValue barcodeECLevel; + for (int32_t i = 0; i < codewords->GetSize(); i++) { + CBC_Codeword* codeword = (CBC_Codeword*)codewords->GetAt(i); + if (codeword == NULL) { + continue; + } + codeword->setRowNumberAsRowIndicatorColumn(); + int32_t rowIndicatorValue = codeword->getValue() % 30; + int32_t codewordRowNumber = codeword->getRowNumber(); + if (!m_isLeft) { + codewordRowNumber += 2; + } + switch (codewordRowNumber % 3) { + case 0: + barcodeRowCountUpperPart.setValue(rowIndicatorValue * 3 + 1); + break; + case 1: + barcodeECLevel.setValue(rowIndicatorValue / 3); + barcodeRowCountLowerPart.setValue(rowIndicatorValue % 3); + break; + case 2: + barcodeColumnCount.setValue(rowIndicatorValue + 1); + break; + } + } + if ((barcodeColumnCount.getValue()->GetSize() == 0) || + (barcodeRowCountUpperPart.getValue()->GetSize() == 0) || + (barcodeRowCountLowerPart.getValue()->GetSize() == 0) || + (barcodeECLevel.getValue()->GetSize() == 0) || + barcodeColumnCount.getValue()->GetAt(0) < 1 || + barcodeRowCountUpperPart.getValue()->GetAt(0) + + barcodeRowCountLowerPart.getValue()->GetAt(0) < + CBC_PDF417Common::MIN_ROWS_IN_BARCODE || + barcodeRowCountUpperPart.getValue()->GetAt(0) + + barcodeRowCountLowerPart.getValue()->GetAt(0) > + CBC_PDF417Common::MAX_ROWS_IN_BARCODE) { + return NULL; + } + CBC_BarcodeMetadata* barcodeMetadata = + new CBC_BarcodeMetadata(barcodeColumnCount.getValue()->GetAt(0), + barcodeRowCountUpperPart.getValue()->GetAt(0), + barcodeRowCountLowerPart.getValue()->GetAt(0), + barcodeECLevel.getValue()->GetAt(0)); + removeIncorrectCodewords(codewords, *barcodeMetadata); + return barcodeMetadata; +} +FX_BOOL CBC_DetectionResultRowIndicatorColumn::isLeft() { + return m_isLeft; +} +CFX_ByteString CBC_DetectionResultRowIndicatorColumn::toString() { + return (CFX_ByteString) "IsLeft: " + (CFX_ByteString)m_isLeft + '\n' + + CBC_DetectionResultColumn::toString(); +} +void CBC_DetectionResultRowIndicatorColumn::removeIncorrectCodewords( + CFX_PtrArray* codewords, + CBC_BarcodeMetadata barcodeMetadata) { + for (int32_t codewordRow = 0; codewordRow < codewords->GetSize(); + codewordRow++) { + CBC_Codeword* codeword = (CBC_Codeword*)codewords->GetAt(codewordRow); + if (codeword == NULL) { + continue; + } + int32_t rowIndicatorValue = codeword->getValue() % 30; + int32_t codewordRowNumber = codeword->getRowNumber(); + if (codewordRowNumber > barcodeMetadata.getRowCount()) { + codewords->SetAt(codewordRow, NULL); + continue; + } + if (!m_isLeft) { + codewordRowNumber += 2; + } + switch (codewordRowNumber % 3) { + case 0: + if (rowIndicatorValue * 3 + 1 != + barcodeMetadata.getRowCountUpperPart()) { + codewords->SetAt(codewordRow, NULL); + } + break; + case 1: + if (rowIndicatorValue / 3 != + barcodeMetadata.getErrorCorrectionLevel() || + rowIndicatorValue % 3 != barcodeMetadata.getRowCountLowerPart()) { + codewords->SetAt(codewordRow, NULL); + } + break; + case 2: + if (rowIndicatorValue + 1 != barcodeMetadata.getColumnCount()) { + codewords->SetAt(codewordRow, NULL); + } + break; + } + } +} diff --git a/xfa/fxbarcode/pdf417/BC_PDF417DetectionResultRowIndicatorColumn.h b/xfa/fxbarcode/pdf417/BC_PDF417DetectionResultRowIndicatorColumn.h new file mode 100644 index 0000000000..dfe6a069d6 --- /dev/null +++ b/xfa/fxbarcode/pdf417/BC_PDF417DetectionResultRowIndicatorColumn.h @@ -0,0 +1,34 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef XFA_FXBARCODE_PDF417_BC_PDF417DETECTIONRESULTROWINDICATORCOLUMN_H_ +#define XFA_FXBARCODE_PDF417_BC_PDF417DETECTIONRESULTROWINDICATORCOLUMN_H_ + +class CBC_BarcodeMetadata; +class CBC_BoundingBox; +class CBC_DetectionResultRowIndicatorColumn; +class CBC_DetectionResultRowIndicatorColumn : public CBC_DetectionResultColumn { + public: + CBC_DetectionResultRowIndicatorColumn(CBC_BoundingBox* boundingBox, + FX_BOOL isLeft); + virtual ~CBC_DetectionResultRowIndicatorColumn(); + void setRowNumbers(); + int32_t adjustCompleteIndicatorColumnRowNumbers( + CBC_BarcodeMetadata barcodeMetadata); + CFX_Int32Array* getRowHeights(int32_t& e); + int32_t adjustIncompleteIndicatorColumnRowNumbers( + CBC_BarcodeMetadata barcodeMetadata); + CBC_BarcodeMetadata* getBarcodeMetadata(); + FX_BOOL isLeft(); + CFX_ByteString toString(); + + private: + FX_BOOL m_isLeft; + void removeIncorrectCodewords(CFX_PtrArray* codewords, + CBC_BarcodeMetadata barcodeMetadata); +}; + +#endif // XFA_FXBARCODE_PDF417_BC_PDF417DETECTIONRESULTROWINDICATORCOLUMN_H_ diff --git a/xfa/fxbarcode/pdf417/BC_PDF417Detector.cpp b/xfa/fxbarcode/pdf417/BC_PDF417Detector.cpp new file mode 100644 index 0000000000..cfd52e56dc --- /dev/null +++ b/xfa/fxbarcode/pdf417/BC_PDF417Detector.cpp @@ -0,0 +1,352 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com +// Original code is licensed as follows: +/* + * Copyright 2009 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "xfa/fxbarcode/BC_BinaryBitmap.h" +#include "xfa/fxbarcode/BC_ResultPoint.h" +#include "xfa/fxbarcode/common/BC_CommonBitArray.h" +#include "xfa/fxbarcode/common/BC_CommonBitMatrix.h" +#include "xfa/fxbarcode/pdf417/BC_PDF417Detector.h" +#include "xfa/fxbarcode/pdf417/BC_PDF417DetectorResult.h" +#include "xfa/fxbarcode/utils.h" + +#define INTEGER_MAX 2147483647 + +int32_t CBC_Detector::INDEXES_START_PATTERN[] = {0, 4, 1, 5}; +int32_t CBC_Detector::INDEXES_STOP_PATTERN[] = {6, 2, 7, 3}; +int32_t CBC_Detector::INTEGER_MATH_SHIFT = 8; +int32_t CBC_Detector::PATTERN_MATCH_RESULT_SCALE_FACTOR = 1 + << INTEGER_MATH_SHIFT; +int32_t CBC_Detector::MAX_AVG_VARIANCE = + (int32_t)(PATTERN_MATCH_RESULT_SCALE_FACTOR * 0.42f); +int32_t CBC_Detector::MAX_INDIVIDUAL_VARIANCE = + (int32_t)(PATTERN_MATCH_RESULT_SCALE_FACTOR * 0.8f); +int32_t CBC_Detector::START_PATTERN[] = {8, 1, 1, 1, 1, 1, 1, 3}; +int32_t CBC_Detector::STOP_PATTERN[] = {7, 1, 1, 3, 1, 1, 1, 2, 1}; +int32_t CBC_Detector::MAX_PIXEL_DRIFT = 3; +int32_t CBC_Detector::MAX_PATTERN_DRIFT = 5; +int32_t CBC_Detector::SKIPPED_ROW_COUNT_MAX = 25; +int32_t CBC_Detector::ROW_STEP = 5; +int32_t CBC_Detector::BARCODE_MIN_HEIGHT = 10; + +CBC_Detector::CBC_Detector() {} +CBC_Detector::~CBC_Detector() {} +CBC_PDF417DetectorResult* CBC_Detector::detect(CBC_BinaryBitmap* image, + int32_t hints, + FX_BOOL multiple, + int32_t& e) { + CBC_CommonBitMatrix* bitMatrix = image->GetBlackMatrix(e); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + CFX_PtrArray* barcodeCoordinates = detect(multiple, bitMatrix); + if (barcodeCoordinates->GetSize() == 0) { + rotate180(bitMatrix); + barcodeCoordinates = detect(multiple, bitMatrix); + } + if (barcodeCoordinates->GetSize() == 0) { + e = BCExceptionUnSupportedBarcode; + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + } + CBC_PDF417DetectorResult* detectorResult = + new CBC_PDF417DetectorResult(bitMatrix, barcodeCoordinates); + return detectorResult; +} +void CBC_Detector::rotate180(CBC_CommonBitMatrix* bitMatrix) { + int32_t width = bitMatrix->GetWidth(); + int32_t height = bitMatrix->GetHeight(); + CBC_CommonBitArray* firstRowBitArray = new CBC_CommonBitArray(width); + CBC_CommonBitArray* secondRowBitArray = new CBC_CommonBitArray(width); + CBC_CommonBitArray* tmpBitArray = new CBC_CommonBitArray(width); + for (int32_t y = 0; y<(height + 1)>> 1; y++) { + CBC_CommonBitArray* temp = + bitMatrix->GetRow(height - 1 - y, secondRowBitArray); + CBC_CommonBitArray* tempfirstRow = firstRowBitArray; + firstRowBitArray = bitMatrix->GetRow(y, tempfirstRow); + delete tempfirstRow; + CBC_CommonBitArray* row = mirror(temp, tmpBitArray); + delete temp; + bitMatrix->SetRow(y, row); + delete row; + CBC_CommonBitArray* rowfirstRow = mirror(firstRowBitArray, tmpBitArray); + bitMatrix->SetRow(height - 1 - y, rowfirstRow); + delete rowfirstRow; + } + delete tmpBitArray; + delete firstRowBitArray; + delete secondRowBitArray; +} +CBC_CommonBitArray* CBC_Detector::mirror(CBC_CommonBitArray* input, + CBC_CommonBitArray* result) { + CBC_CommonBitArray* array = new CBC_CommonBitArray(result->GetSize()); + array->Clear(); + int32_t size = input->GetSize(); + for (int32_t i = 0; i < size; i++) { + if (input->Get(i)) { + array->Set(size - 1 - i); + } + } + return array; +} +CFX_PtrArray* CBC_Detector::detect(FX_BOOL multiple, + CBC_CommonBitMatrix* bitMatrix) { + CFX_PtrArray* barcodeCoordinates = new CFX_PtrArray; + int32_t row = 0; + int32_t column = 0; + FX_BOOL foundBarcodeInRow = FALSE; + while (row < bitMatrix->GetHeight()) { + CFX_PtrArray* vertices = findVertices(bitMatrix, row, column); + if (vertices->GetAt(0) == NULL && vertices->GetAt(3) == NULL) { + if (!foundBarcodeInRow) { + if (vertices) { + delete (vertices); + } + break; + } + foundBarcodeInRow = FALSE; + column = 0; + for (int32_t i = 0; i < barcodeCoordinates->GetSize(); i++) { + CFX_PtrArray* barcodeCoordinate = + (CFX_PtrArray*)barcodeCoordinates->GetAt(i); + if (barcodeCoordinate->GetAt(1)) { + row = row > ((CBC_ResultPoint*)barcodeCoordinate->GetAt(1))->GetY(); + } + if (barcodeCoordinate->GetAt(3)) { + row = row > ((CBC_ResultPoint*)barcodeCoordinate->GetAt(3))->GetY(); + } + } + row += ROW_STEP; + if (vertices) { + delete (vertices); + } + continue; + } + foundBarcodeInRow = TRUE; + barcodeCoordinates->Add(vertices); + if (!multiple) { + break; + } + if (vertices->GetAt(2)) { + column = (int32_t)((CBC_ResultPoint*)vertices->GetAt(2))->GetX(); + row = (int32_t)((CBC_ResultPoint*)vertices->GetAt(2))->GetY(); + } else { + column = (int32_t)((CBC_ResultPoint*)vertices->GetAt(4))->GetX(); + row = (int32_t)((CBC_ResultPoint*)vertices->GetAt(4))->GetY(); + } + } + return barcodeCoordinates; +} +CFX_PtrArray* CBC_Detector::findVertices(CBC_CommonBitMatrix* matrix, + int32_t startRow, + int32_t startColumn) { + int32_t height = matrix->GetHeight(); + int32_t width = matrix->GetWidth(); + CFX_PtrArray* result = new CFX_PtrArray; + result->SetSize(8); + CFX_PtrArray* startptr = findRowsWithPattern( + matrix, height, width, startRow, startColumn, START_PATTERN, + sizeof(START_PATTERN) / sizeof(START_PATTERN[0])); + copyToResult( + result, startptr, INDEXES_START_PATTERN, + sizeof(INDEXES_START_PATTERN) / sizeof(INDEXES_START_PATTERN[0])); + startptr->RemoveAll(); + delete startptr; + if (result->GetAt(4)) { + startColumn = (int32_t)((CBC_ResultPoint*)result->GetAt(4))->GetX(); + startRow = (int32_t)((CBC_ResultPoint*)result->GetAt(4))->GetY(); + } + CFX_PtrArray* stopptr = findRowsWithPattern( + matrix, height, width, startRow, startColumn, STOP_PATTERN, + sizeof(STOP_PATTERN) / sizeof(STOP_PATTERN[0])); + copyToResult(result, stopptr, INDEXES_STOP_PATTERN, + sizeof(INDEXES_STOP_PATTERN) / sizeof(INDEXES_STOP_PATTERN[0])); + stopptr->RemoveAll(); + delete stopptr; + return result; +} +void CBC_Detector::copyToResult(CFX_PtrArray* result, + CFX_PtrArray* tmpResult, + int32_t* destinationIndexes, + int32_t destinationLength) { + for (int32_t i = 0; i < destinationLength; i++) { + result->SetAt(destinationIndexes[i], tmpResult->GetAt(i)); + } +} +CFX_PtrArray* CBC_Detector::findRowsWithPattern(CBC_CommonBitMatrix* matrix, + int32_t height, + int32_t width, + int32_t startRow, + int32_t startColumn, + int32_t* pattern, + int32_t patternLength) { + CFX_PtrArray* result = new CFX_PtrArray; + result->SetSize(4); + FX_BOOL found = FALSE; + CFX_Int32Array counters; + counters.SetSize(patternLength); + for (; startRow < height; startRow += ROW_STEP) { + CFX_Int32Array* loc = + findGuardPattern(matrix, startColumn, startRow, width, FALSE, pattern, + patternLength, counters); + if (loc) { + while (startRow > 0) { + CFX_Int32Array* previousRowLoc = + findGuardPattern(matrix, startColumn, --startRow, width, FALSE, + pattern, patternLength, counters); + if (previousRowLoc) { + delete loc; + loc = previousRowLoc; + } else { + startRow++; + break; + } + } + result->SetAt( + 0, new CBC_ResultPoint((FX_FLOAT)loc->GetAt(0), (FX_FLOAT)startRow)); + result->SetAt( + 1, new CBC_ResultPoint((FX_FLOAT)loc->GetAt(1), (FX_FLOAT)startRow)); + found = TRUE; + delete loc; + break; + } + } + int32_t stopRow = startRow + 1; + if (found) { + int32_t skippedRowCount = 0; + CFX_Int32Array previousRowLoc; + previousRowLoc.Add((int32_t)((CBC_ResultPoint*)result->GetAt(0))->GetX()); + previousRowLoc.Add((int32_t)((CBC_ResultPoint*)result->GetAt(1))->GetX()); + for (; stopRow < height; stopRow++) { + CFX_Int32Array* loc = + findGuardPattern(matrix, previousRowLoc[0], stopRow, width, FALSE, + pattern, patternLength, counters); + if (loc && abs(previousRowLoc[0] - loc->GetAt(0)) < MAX_PATTERN_DRIFT && + abs(previousRowLoc[1] - loc->GetAt(1)) < MAX_PATTERN_DRIFT) { + previousRowLoc.Copy(*loc); + skippedRowCount = 0; + } else { + if (skippedRowCount > SKIPPED_ROW_COUNT_MAX) { + delete loc; + break; + } else { + skippedRowCount++; + } + } + delete loc; + } + stopRow -= skippedRowCount + 1; + result->SetAt(2, new CBC_ResultPoint((FX_FLOAT)previousRowLoc.GetAt(0), + (FX_FLOAT)stopRow)); + result->SetAt(3, new CBC_ResultPoint((FX_FLOAT)previousRowLoc.GetAt(1), + (FX_FLOAT)stopRow)); + } + if (stopRow - startRow < BARCODE_MIN_HEIGHT) { + for (int32_t i = 0; i < result->GetSize(); i++) { + result->SetAt(i, NULL); + } + } + return result; +} +CFX_Int32Array* CBC_Detector::findGuardPattern(CBC_CommonBitMatrix* matrix, + int32_t column, + int32_t row, + int32_t width, + FX_BOOL whiteFirst, + int32_t* pattern, + int32_t patternLength, + CFX_Int32Array& counters) { + for (int32_t i = 0; i < counters.GetSize(); i++) { + counters.SetAt(i, 0); + } + FX_BOOL isWhite = whiteFirst; + int32_t patternStart = column; + int32_t pixelDrift = 0; + CFX_Int32Array* intarray = new CFX_Int32Array; + while (matrix->Get(patternStart, row) && patternStart > 0 && + pixelDrift++ < MAX_PIXEL_DRIFT) { + patternStart--; + } + int32_t x = patternStart; + int32_t counterPosition = 0; + for (; x < width; x++) { + FX_BOOL pixel = matrix->Get(x, row); + if (pixel ^ isWhite) { + counters[counterPosition]++; + } else { + if (counterPosition == patternLength - 1) { + if (patternMatchVariance(counters, pattern, MAX_INDIVIDUAL_VARIANCE) < + MAX_AVG_VARIANCE) { + intarray->Add(patternStart); + intarray->Add(x); + return intarray; + } + patternStart += counters[0] + counters[1]; + for (int32_t l = 2, k = 0; l < patternLength; l++, k++) { + counters.SetAt(k, counters.GetAt(l)); + } + counters.SetAt(patternLength - 2, 0); + counters.SetAt(patternLength - 1, 0); + counterPosition--; + } else { + counterPosition++; + } + counters[counterPosition] = 1; + isWhite = !isWhite; + } + } + if (counterPosition == patternLength - 1) { + if (patternMatchVariance(counters, pattern, MAX_INDIVIDUAL_VARIANCE) < + MAX_AVG_VARIANCE) { + intarray->Add(patternStart); + intarray->Add(x - 1); + return intarray; + } + } + delete intarray; + return NULL; +} +int32_t CBC_Detector::patternMatchVariance(CFX_Int32Array& counters, + int32_t* pattern, + int32_t maxIndividualVariance) { + int32_t numCounters = counters.GetSize(); + int32_t total = 0; + int32_t patternLength = 0; + for (int32_t i = 0; i < numCounters; i++) { + total += counters[i]; + patternLength += pattern[i]; + } + if (total < patternLength) { + return INTEGER_MAX; + } + int32_t unitBarWidth = (total << INTEGER_MATH_SHIFT) / patternLength; + maxIndividualVariance = + (maxIndividualVariance * unitBarWidth) >> INTEGER_MATH_SHIFT; + int32_t totalVariance = 0; + for (int32_t x = 0; x < numCounters; x++) { + int32_t counter = counters[x] << INTEGER_MATH_SHIFT; + int32_t scaledPattern = pattern[x] * unitBarWidth; + int32_t variance = counter > scaledPattern ? counter - scaledPattern + : scaledPattern - counter; + if (variance > maxIndividualVariance) { + return INTEGER_MAX; + } + totalVariance += variance; + } + return totalVariance / total; +} diff --git a/xfa/fxbarcode/pdf417/BC_PDF417Detector.h b/xfa/fxbarcode/pdf417/BC_PDF417Detector.h new file mode 100644 index 0000000000..dda039d6d5 --- /dev/null +++ b/xfa/fxbarcode/pdf417/BC_PDF417Detector.h @@ -0,0 +1,69 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef XFA_FXBARCODE_PDF417_BC_PDF417DETECTOR_H_ +#define XFA_FXBARCODE_PDF417_BC_PDF417DETECTOR_H_ + +class CBC_PDF417DetectorResult; +class CBC_BinaryBitmap; +class CBC_CommonBitMatrix; +class CBC_CommonBitArray; + +class CBC_Detector { + public: + CBC_Detector(); + virtual ~CBC_Detector(); + static CBC_PDF417DetectorResult* detect(CBC_BinaryBitmap* image, + int32_t hints, + FX_BOOL multiple, + int32_t& e); + static void rotate180(CBC_CommonBitMatrix* bitMatrix); + static CBC_CommonBitArray* mirror(CBC_CommonBitArray* input, + CBC_CommonBitArray* result); + + private: + static int32_t INDEXES_START_PATTERN[]; + static int32_t INDEXES_STOP_PATTERN[]; + static int32_t INTEGER_MATH_SHIFT; + static int32_t PATTERN_MATCH_RESULT_SCALE_FACTOR; + static int32_t MAX_AVG_VARIANCE; + static int32_t MAX_INDIVIDUAL_VARIANCE; + static int32_t START_PATTERN[]; + static int32_t STOP_PATTERN[]; + static int32_t MAX_PIXEL_DRIFT; + static int32_t MAX_PATTERN_DRIFT; + static int32_t SKIPPED_ROW_COUNT_MAX; + static int32_t ROW_STEP; + static int32_t BARCODE_MIN_HEIGHT; + static CFX_PtrArray* detect(FX_BOOL multiple, CBC_CommonBitMatrix* bitMatrix); + static CFX_PtrArray* findVertices(CBC_CommonBitMatrix* matrix, + int32_t startRow, + int32_t startColumn); + static void copyToResult(CFX_PtrArray* result, + CFX_PtrArray* tmpResult, + int32_t* destinationIndexes, + int32_t destinationLength); + static CFX_PtrArray* findRowsWithPattern(CBC_CommonBitMatrix* matrix, + int32_t height, + int32_t width, + int32_t startRow, + int32_t startColumn, + int32_t* pattern, + int32_t patternLength); + static CFX_Int32Array* findGuardPattern(CBC_CommonBitMatrix* matrix, + int32_t column, + int32_t row, + int32_t width, + FX_BOOL whiteFirst, + int32_t* pattern, + int32_t patternLength, + CFX_Int32Array& counters); + static int32_t patternMatchVariance(CFX_Int32Array& counters, + int32_t* pattern, + int32_t maxIndividualVariance); +}; + +#endif // XFA_FXBARCODE_PDF417_BC_PDF417DETECTOR_H_ diff --git a/xfa/fxbarcode/pdf417/BC_PDF417DetectorResult.cpp b/xfa/fxbarcode/pdf417/BC_PDF417DetectorResult.cpp new file mode 100644 index 0000000000..557d50d951 --- /dev/null +++ b/xfa/fxbarcode/pdf417/BC_PDF417DetectorResult.cpp @@ -0,0 +1,50 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com +// Original code is licensed as follows: +/* + * Copyright 2007 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "xfa/fxbarcode/BC_ResultPoint.h" +#include "xfa/fxbarcode/common/BC_CommonBitMatrix.h" +#include "xfa/fxbarcode/pdf417/BC_PDF417DetectorResult.h" + +CBC_PDF417DetectorResult::CBC_PDF417DetectorResult(CBC_CommonBitMatrix* bits, + CFX_PtrArray* points) { + m_bits = bits; + m_points = points; +} +CBC_PDF417DetectorResult::~CBC_PDF417DetectorResult() { + for (int32_t i = 0; i < m_points->GetSize(); i++) { + CFX_PtrArray* temp = (CFX_PtrArray*)m_points->GetAt(i); + for (int32_t j = 0; j < temp->GetSize(); j++) { + delete (CBC_ResultPoint*)temp->GetAt(j); + } + temp->RemoveAll(); + delete temp; + } + m_points->RemoveAll(); + delete m_points; +} +CBC_CommonBitMatrix* CBC_PDF417DetectorResult::getBits() { + return m_bits; +} + +CFX_PtrArray* CBC_PDF417DetectorResult::getPoints() { + return m_points; +} diff --git a/xfa/fxbarcode/pdf417/BC_PDF417DetectorResult.h b/xfa/fxbarcode/pdf417/BC_PDF417DetectorResult.h new file mode 100644 index 0000000000..0eea685fbc --- /dev/null +++ b/xfa/fxbarcode/pdf417/BC_PDF417DetectorResult.h @@ -0,0 +1,26 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef XFA_FXBARCODE_PDF417_BC_PDF417DETECTORRESULT_H_ +#define XFA_FXBARCODE_PDF417_BC_PDF417DETECTORRESULT_H_ + +#include "core/include/fxcrt/fx_basic.h" + +class CBC_CommonBitMatrix; + +class CBC_PDF417DetectorResult { + public: + CBC_PDF417DetectorResult(CBC_CommonBitMatrix* bits, CFX_PtrArray* points); + virtual ~CBC_PDF417DetectorResult(); + CBC_CommonBitMatrix* getBits(); + CFX_PtrArray* getPoints(); + + private: + CBC_CommonBitMatrix* m_bits; + CFX_PtrArray* m_points; +}; + +#endif // XFA_FXBARCODE_PDF417_BC_PDF417DETECTORRESULT_H_ diff --git a/xfa/fxbarcode/pdf417/BC_PDF417Dimensions.cpp b/xfa/fxbarcode/pdf417/BC_PDF417Dimensions.cpp new file mode 100644 index 0000000000..3f0b3145b0 --- /dev/null +++ b/xfa/fxbarcode/pdf417/BC_PDF417Dimensions.cpp @@ -0,0 +1,46 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com +// Original code is licensed as follows: +/* + * Copyright 2012 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "xfa/fxbarcode/pdf417/BC_PDF417Dimensions.h" + +CBC_Dimensions::CBC_Dimensions(int32_t minCols, + int32_t maxCols, + int32_t minRows, + int32_t maxRows) { + m_minCols = minCols; + m_maxCols = maxCols; + m_minRows = minRows; + m_maxRows = maxRows; +} +CBC_Dimensions::~CBC_Dimensions() {} +int32_t CBC_Dimensions::getMinCols() { + return m_minCols; +} +int32_t CBC_Dimensions::getMaxCols() { + return m_maxCols; +} +int32_t CBC_Dimensions::getMinRows() { + return m_minRows; +} +int32_t CBC_Dimensions::getMaxRows() { + return m_maxRows; +} diff --git a/xfa/fxbarcode/pdf417/BC_PDF417Dimensions.h b/xfa/fxbarcode/pdf417/BC_PDF417Dimensions.h new file mode 100644 index 0000000000..622ad236bc --- /dev/null +++ b/xfa/fxbarcode/pdf417/BC_PDF417Dimensions.h @@ -0,0 +1,31 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef XFA_FXBARCODE_PDF417_BC_PDF417DIMENSIONS_H_ +#define XFA_FXBARCODE_PDF417_BC_PDF417DIMENSIONS_H_ + +#include <stdint.h> + +class CBC_Dimensions { + public: + CBC_Dimensions(int32_t minCols, + int32_t maxCols, + int32_t minRows, + int32_t maxRows); + virtual ~CBC_Dimensions(); + int32_t getMinCols(); + int32_t getMaxCols(); + int32_t getMinRows(); + int32_t getMaxRows(); + + private: + int32_t m_minCols; + int32_t m_maxCols; + int32_t m_minRows; + int32_t m_maxRows; +}; + +#endif // XFA_FXBARCODE_PDF417_BC_PDF417DIMENSIONS_H_ diff --git a/xfa/fxbarcode/pdf417/BC_PDF417ECErrorCorrection.cpp b/xfa/fxbarcode/pdf417/BC_PDF417ECErrorCorrection.cpp new file mode 100644 index 0000000000..830b65e199 --- /dev/null +++ b/xfa/fxbarcode/pdf417/BC_PDF417ECErrorCorrection.cpp @@ -0,0 +1,389 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com +// Original code is licensed as follows: +/* + * Copyright 2012 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "xfa/fxbarcode/pdf417/BC_PDF417Common.h" +#include "xfa/fxbarcode/pdf417/BC_PDF417ECErrorCorrection.h" +#include "xfa/fxbarcode/pdf417/BC_PDF417ECModulusGF.h" +#include "xfa/fxbarcode/pdf417/BC_PDF417ECModulusPoly.h" +#include "xfa/fxbarcode/utils.h" + +CBC_PDF417ECModulusGF* CBC_PDF417ECErrorCorrection::m_field = NULL; + +void CBC_PDF417ECErrorCorrection::Initialize(int32_t& e) { + m_field = + new CBC_PDF417ECModulusGF(CBC_PDF417Common::NUMBER_OF_CODEWORDS, 3, e); +} +void CBC_PDF417ECErrorCorrection::Finalize() { + delete m_field; +} +CBC_PDF417ECErrorCorrection::CBC_PDF417ECErrorCorrection() {} +CBC_PDF417ECErrorCorrection::~CBC_PDF417ECErrorCorrection() {} +int32_t CBC_PDF417ECErrorCorrection::decode(CFX_Int32Array& received, + int32_t numECCodewords, + CFX_Int32Array& erasures, + int32_t& e) { + CBC_PDF417ECModulusPoly poly(m_field, received, e); + BC_EXCEPTION_CHECK_ReturnValue(e, -1); + CFX_Int32Array S; + S.SetSize(numECCodewords); + FX_BOOL error = FALSE; + for (int32_t l = numECCodewords; l > 0; l--) { + int32_t eval = poly.evaluateAt(m_field->exp(l)); + S[numECCodewords - l] = eval; + if (eval != 0) { + error = TRUE; + } + } + if (!error) { + return 0; + } + CBC_PDF417ECModulusPoly* syndrome = + new CBC_PDF417ECModulusPoly(m_field, S, e); + BC_EXCEPTION_CHECK_ReturnValue(e, -1); + CBC_PDF417ECModulusPoly* buildmonomial = + m_field->buildMonomial(numECCodewords, 1, e); + if (e != BCExceptionNO) { + delete syndrome; + return -1; + } + CFX_PtrArray* sigmaOmega = + runEuclideanAlgorithm(buildmonomial, syndrome, numECCodewords, e); + delete buildmonomial; + delete syndrome; + BC_EXCEPTION_CHECK_ReturnValue(e, -1); + CBC_PDF417ECModulusPoly* sigma = + (CBC_PDF417ECModulusPoly*)sigmaOmega->GetAt(0); + CBC_PDF417ECModulusPoly* omega = + (CBC_PDF417ECModulusPoly*)sigmaOmega->GetAt(1); + CFX_Int32Array* errorLocations = findErrorLocations(sigma, e); + if (e != BCExceptionNO) { + for (int32_t i = 0; i < sigmaOmega->GetSize(); i++) { + delete (CBC_PDF417ECModulusPoly*)sigmaOmega->GetAt(i); + } + sigmaOmega->RemoveAll(); + delete sigmaOmega; + return -1; + } + CFX_Int32Array* errorMagnitudes = + findErrorMagnitudes(omega, sigma, *errorLocations, e); + if (e != BCExceptionNO) { + delete errorLocations; + for (int32_t i = 0; i < sigmaOmega->GetSize(); i++) { + delete (CBC_PDF417ECModulusPoly*)sigmaOmega->GetAt(i); + } + sigmaOmega->RemoveAll(); + delete sigmaOmega; + return -1; + } + for (int32_t i = 0; i < errorLocations->GetSize(); i++) { + int32_t log = m_field->log(errorLocations->GetAt(i), e); + + BC_EXCEPTION_CHECK_ReturnValue(e, -1); + int32_t position = received.GetSize() - 1 - log; + if (position < 0) { + e = BCExceptionChecksumException; + delete errorLocations; + delete errorMagnitudes; + for (int32_t j = 0; j < sigmaOmega->GetSize(); j++) { + delete (CBC_PDF417ECModulusPoly*)sigmaOmega->GetAt(j); + } + sigmaOmega->RemoveAll(); + delete sigmaOmega; + return -1; + } + received[position] = + m_field->subtract(received[position], errorMagnitudes->GetAt(i)); + } + int32_t result = errorLocations->GetSize(); + delete errorLocations; + delete errorMagnitudes; + for (int32_t k = 0; k < sigmaOmega->GetSize(); k++) { + delete (CBC_PDF417ECModulusPoly*)sigmaOmega->GetAt(k); + } + sigmaOmega->RemoveAll(); + delete sigmaOmega; + return result; +} +CFX_PtrArray* CBC_PDF417ECErrorCorrection::runEuclideanAlgorithm( + CBC_PDF417ECModulusPoly* a, + CBC_PDF417ECModulusPoly* b, + int32_t R, + int32_t& e) { + if (a->getDegree() < b->getDegree()) { + CBC_PDF417ECModulusPoly* temp = a; + a = b; + b = temp; + } + CBC_PDF417ECModulusPoly* rLast = a; + CBC_PDF417ECModulusPoly* r = b; + CBC_PDF417ECModulusPoly* tLast = m_field->getZero(); + CBC_PDF417ECModulusPoly* t = m_field->getOne(); + CBC_PDF417ECModulusPoly* qtemp = NULL; + CBC_PDF417ECModulusPoly* rtemp = NULL; + CBC_PDF417ECModulusPoly* ttemp = NULL; + int32_t i = 0; + int32_t j = 0; + int32_t m = 0; + int32_t n = 0; + while (r->getDegree() >= R / 2) { + CBC_PDF417ECModulusPoly* rLastLast = rLast; + CBC_PDF417ECModulusPoly* tLastLast = tLast; + rLast = r; + tLast = t; + m = i; + n = j; + if (rLast->isZero()) { + e = BCExceptionChecksumException; + if (qtemp) { + delete qtemp; + } + if (rtemp) { + delete rtemp; + } + if (ttemp) { + delete ttemp; + } + return NULL; + } + r = rLastLast; + CBC_PDF417ECModulusPoly* q = m_field->getZero(); + int32_t denominatorLeadingTerm = rLast->getCoefficient(rLast->getDegree()); + int32_t dltInverse = m_field->inverse(denominatorLeadingTerm, e); + if (e != BCExceptionNO) { + if (qtemp) { + delete qtemp; + } + if (rtemp) { + delete rtemp; + } + if (ttemp) { + delete ttemp; + } + return NULL; + } + while (r->getDegree() >= rLast->getDegree() && !r->isZero()) { + int32_t degreeDiff = r->getDegree() - rLast->getDegree(); + int32_t scale = + m_field->multiply(r->getCoefficient(r->getDegree()), dltInverse); + CBC_PDF417ECModulusPoly* buildmonomial = + m_field->buildMonomial(degreeDiff, scale, e); + if (e != BCExceptionNO) { + if (qtemp) { + delete qtemp; + } + if (rtemp) { + delete rtemp; + } + if (ttemp) { + delete ttemp; + } + return NULL; + } + q = q->add(buildmonomial, e); + delete buildmonomial; + if (qtemp) { + delete qtemp; + } + if (e != BCExceptionNO) { + if (rtemp) { + delete rtemp; + } + if (ttemp) { + delete ttemp; + } + return NULL; + } + qtemp = q; + CBC_PDF417ECModulusPoly* multiply = + rLast->multiplyByMonomial(degreeDiff, scale, e); + if (e != BCExceptionNO) { + if (qtemp) { + delete qtemp; + } + if (rtemp) { + delete rtemp; + } + if (ttemp) { + delete ttemp; + } + return NULL; + } + CBC_PDF417ECModulusPoly* temp = r; + r = temp->subtract(multiply, e); + delete multiply; + if (m > 1 && i > m) { + delete temp; + temp = NULL; + } + if (e != BCExceptionNO) { + if (qtemp) { + delete qtemp; + } + if (rtemp) { + delete rtemp; + } + if (ttemp) { + delete ttemp; + } + return NULL; + } + rtemp = r; + i = m + 1; + } + ttemp = q->multiply(tLast, e); + if (qtemp) { + delete qtemp; + qtemp = NULL; + } + if (e != BCExceptionNO) { + if (rtemp) { + delete rtemp; + } + if (ttemp) { + delete ttemp; + } + return NULL; + } + t = ttemp->subtract(tLastLast, e); + if (n > 1 && j > n) { + delete tLastLast; + } + delete ttemp; + if (e != BCExceptionNO) { + if (rtemp) { + delete rtemp; + } + return NULL; + } + ttemp = t; + t = ttemp->negative(e); + delete ttemp; + if (e != BCExceptionNO) { + if (rtemp) { + delete rtemp; + } + return NULL; + } + ttemp = t; + j++; + } + int32_t sigmaTildeAtZero = t->getCoefficient(0); + if (sigmaTildeAtZero == 0) { + e = BCExceptionChecksumException; + if (rtemp) { + delete rtemp; + } + if (ttemp) { + delete ttemp; + } + return NULL; + } + int32_t inverse = m_field->inverse(sigmaTildeAtZero, e); + if (e != BCExceptionNO) { + if (rtemp) { + delete rtemp; + } + if (ttemp) { + delete ttemp; + } + return NULL; + } + CBC_PDF417ECModulusPoly* sigma = t->multiply(inverse, e); + if (ttemp) { + delete ttemp; + } + if (e != BCExceptionNO) { + if (rtemp) { + delete rtemp; + } + return NULL; + } + CBC_PDF417ECModulusPoly* omega = r->multiply(inverse, e); + if (rtemp) { + delete rtemp; + } + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + CFX_PtrArray* modulusPoly = new CFX_PtrArray; + modulusPoly->Add(sigma); + modulusPoly->Add(omega); + return modulusPoly; +} +CFX_Int32Array* CBC_PDF417ECErrorCorrection::findErrorLocations( + CBC_PDF417ECModulusPoly* errorLocator, + int32_t& e) { + int32_t numErrors = errorLocator->getDegree(); + CFX_Int32Array* result = new CFX_Int32Array; + result->SetSize(numErrors); + int32_t ee = 0; + for (int32_t i = 1; i < m_field->getSize() && ee < numErrors; i++) { + if (errorLocator->evaluateAt(i) == 0) { + result->SetAt(ee, m_field->inverse(i, e)); + if (e != BCExceptionNO) { + delete result; + return NULL; + } + ee++; + } + } + if (ee != numErrors) { + e = BCExceptionChecksumException; + delete result; + return NULL; + } + return result; +} +CFX_Int32Array* CBC_PDF417ECErrorCorrection::findErrorMagnitudes( + CBC_PDF417ECModulusPoly* errorEvaluator, + CBC_PDF417ECModulusPoly* errorLocator, + CFX_Int32Array& errorLocations, + int32_t& e) { + int32_t errorLocatorDegree = errorLocator->getDegree(); + CFX_Int32Array formalDerivativeCoefficients; + formalDerivativeCoefficients.SetSize(errorLocatorDegree); + for (int32_t l = 1; l <= errorLocatorDegree; l++) { + formalDerivativeCoefficients[errorLocatorDegree - l] = + m_field->multiply(l, errorLocator->getCoefficient(l)); + } + CBC_PDF417ECModulusPoly formalDerivative(m_field, + formalDerivativeCoefficients, e); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + int32_t s = errorLocations.GetSize(); + CFX_Int32Array* result = new CFX_Int32Array; + result->SetSize(s); + for (int32_t i = 0; i < s; i++) { + int32_t xiInverse = m_field->inverse(errorLocations[i], e); + if (e != BCExceptionNO) { + delete result; + return NULL; + } + int32_t numerator = + m_field->subtract(0, errorEvaluator->evaluateAt(xiInverse)); + int32_t denominator = + m_field->inverse(formalDerivative.evaluateAt(xiInverse), e); + if (e != BCExceptionNO) { + delete result; + return NULL; + } + result->SetAt(i, m_field->multiply(numerator, denominator)); + } + return result; +} diff --git a/xfa/fxbarcode/pdf417/BC_PDF417ECErrorCorrection.h b/xfa/fxbarcode/pdf417/BC_PDF417ECErrorCorrection.h new file mode 100644 index 0000000000..d7b56defe9 --- /dev/null +++ b/xfa/fxbarcode/pdf417/BC_PDF417ECErrorCorrection.h @@ -0,0 +1,39 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef XFA_FXBARCODE_PDF417_BC_PDF417ECERRORCORRECTION_H_ +#define XFA_FXBARCODE_PDF417_BC_PDF417ECERRORCORRECTION_H_ + +class CBC_PDF417ECModulusGF; +class CBC_PDF417ECModulusPoly; +class CBC_PDF417ECErrorCorrection { + public: + CBC_PDF417ECErrorCorrection(); + virtual ~CBC_PDF417ECErrorCorrection(); + static void Initialize(int32_t& e); + static void Finalize(); + static int32_t decode(CFX_Int32Array& received, + int32_t numECCodewords, + CFX_Int32Array& erasures, + int32_t& e); + + private: + static CBC_PDF417ECModulusGF* m_field; + static CFX_PtrArray* runEuclideanAlgorithm(CBC_PDF417ECModulusPoly* a, + CBC_PDF417ECModulusPoly* b, + int32_t R, + int32_t& e); + static CFX_Int32Array* findErrorLocations( + CBC_PDF417ECModulusPoly* errorLocator, + int32_t& e); + static CFX_Int32Array* findErrorMagnitudes( + CBC_PDF417ECModulusPoly* errorEvaluator, + CBC_PDF417ECModulusPoly* errorLocator, + CFX_Int32Array& errorLocations, + int32_t& e); +}; + +#endif // XFA_FXBARCODE_PDF417_BC_PDF417ECERRORCORRECTION_H_ diff --git a/xfa/fxbarcode/pdf417/BC_PDF417ECModulusGF.cpp b/xfa/fxbarcode/pdf417/BC_PDF417ECModulusGF.cpp new file mode 100644 index 0000000000..4779d80157 --- /dev/null +++ b/xfa/fxbarcode/pdf417/BC_PDF417ECModulusGF.cpp @@ -0,0 +1,120 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com +// Original code is licensed as follows: +/* + * Copyright 2012 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "xfa/fxbarcode/pdf417/BC_PDF417Common.h" +#include "xfa/fxbarcode/pdf417/BC_PDF417ECModulusGF.h" +#include "xfa/fxbarcode/pdf417/BC_PDF417ECModulusPoly.h" +#include "xfa/fxbarcode/utils.h" + +CBC_PDF417ECModulusGF* CBC_PDF417ECModulusGF::PDF417_GF = NULL; +void CBC_PDF417ECModulusGF::Initialize(int32_t& e) { + PDF417_GF = + new CBC_PDF417ECModulusGF(CBC_PDF417Common::NUMBER_OF_CODEWORDS, 3, e); +} +void CBC_PDF417ECModulusGF::Finalize() { + delete PDF417_GF; +} +CBC_PDF417ECModulusGF::CBC_PDF417ECModulusGF(int32_t modulus, + int32_t generator, + int32_t& e) { + m_modulus = modulus; + m_expTable.SetSize(modulus); + m_logTable.SetSize(modulus); + int32_t x = 1; + for (int32_t i = 0; i < modulus; i++) { + m_expTable[i] = x; + x = (x * generator) % modulus; + } + for (int32_t j = 0; j < modulus - 1; j++) { + m_logTable[m_expTable[j]] = j; + } + CFX_Int32Array zero; + zero.Add(0); + m_zero = new CBC_PDF417ECModulusPoly(this, zero, e); + CFX_Int32Array one; + one.Add(1); + m_one = new CBC_PDF417ECModulusPoly(this, one, e); +} +CBC_PDF417ECModulusGF::~CBC_PDF417ECModulusGF() { + delete m_zero; + delete m_one; +} +CBC_PDF417ECModulusPoly* CBC_PDF417ECModulusGF::getZero() { + return m_zero; +} +CBC_PDF417ECModulusPoly* CBC_PDF417ECModulusGF::getOne() { + return m_one; +} +CBC_PDF417ECModulusPoly* CBC_PDF417ECModulusGF::buildMonomial( + int32_t degree, + int32_t coefficient, + int32_t& e) { + if (degree < 0) { + e = BCExceptionIllegalArgument; + return NULL; + } + CBC_PDF417ECModulusPoly* modulusPoly = NULL; + if (coefficient == 0) { + modulusPoly = new CBC_PDF417ECModulusPoly(m_zero->getField(), + m_zero->getCoefficients(), e); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + return modulusPoly; + } + CFX_Int32Array coefficients; + coefficients.SetSize(degree + 1); + coefficients[0] = coefficient; + modulusPoly = new CBC_PDF417ECModulusPoly(this, coefficients, e); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + return modulusPoly; +} +int32_t CBC_PDF417ECModulusGF::add(int32_t a, int32_t b) { + return (a + b) % m_modulus; +} +int32_t CBC_PDF417ECModulusGF::subtract(int32_t a, int32_t b) { + return (m_modulus + a - b) % m_modulus; +} +int32_t CBC_PDF417ECModulusGF::exp(int32_t a) { + return m_expTable[a]; +} +int32_t CBC_PDF417ECModulusGF::log(int32_t a, int32_t& e) { + if (a == 0) { + e = BCExceptionIllegalArgument; + return -1; + } + return m_logTable[a]; +} +int32_t CBC_PDF417ECModulusGF::inverse(int32_t a, int32_t& e) { + if (a == 0) { + e = BCExceptionIllegalArgument; + return -1; + } + return m_expTable[m_modulus - m_logTable[a] - 1]; +} +int32_t CBC_PDF417ECModulusGF::multiply(int32_t a, int32_t b) { + if (a == 0 || b == 0) { + return 0; + } + return m_expTable[(m_logTable[a] + m_logTable[b]) % (m_modulus - 1)]; +} +int32_t CBC_PDF417ECModulusGF::getSize() { + return m_modulus; +} diff --git a/xfa/fxbarcode/pdf417/BC_PDF417ECModulusGF.h b/xfa/fxbarcode/pdf417/BC_PDF417ECModulusGF.h new file mode 100644 index 0000000000..094e00164d --- /dev/null +++ b/xfa/fxbarcode/pdf417/BC_PDF417ECModulusGF.h @@ -0,0 +1,39 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef XFA_FXBARCODE_PDF417_BC_PDF417ECMODULUSGF_H_ +#define XFA_FXBARCODE_PDF417_BC_PDF417ECMODULUSGF_H_ + +class CBC_PDF417ECModulusPoly; +class CBC_PDF417ECModulusGF { + public: + CBC_PDF417ECModulusGF(int32_t modulus, int32_t generator, int32_t& e); + virtual ~CBC_PDF417ECModulusGF(); + static void Initialize(int32_t& e); + static void Finalize(); + CBC_PDF417ECModulusPoly* getZero(); + CBC_PDF417ECModulusPoly* getOne(); + CBC_PDF417ECModulusPoly* buildMonomial(int32_t degree, + int32_t coefficient, + int32_t& e); + int32_t add(int32_t a, int32_t b); + int32_t subtract(int32_t a, int32_t b); + int32_t exp(int32_t a); + int32_t log(int32_t a, int32_t& e); + int32_t inverse(int32_t a, int32_t& e); + int32_t multiply(int32_t a, int32_t b); + int32_t getSize(); + static CBC_PDF417ECModulusGF* PDF417_GF; + + private: + CFX_Int32Array m_expTable; + CFX_Int32Array m_logTable; + CBC_PDF417ECModulusPoly* m_zero; + CBC_PDF417ECModulusPoly* m_one; + int32_t m_modulus; +}; + +#endif // XFA_FXBARCODE_PDF417_BC_PDF417ECMODULUSGF_H_ diff --git a/xfa/fxbarcode/pdf417/BC_PDF417ECModulusPoly.cpp b/xfa/fxbarcode/pdf417/BC_PDF417ECModulusPoly.cpp new file mode 100644 index 0000000000..d0bbe5ab0a --- /dev/null +++ b/xfa/fxbarcode/pdf417/BC_PDF417ECModulusPoly.cpp @@ -0,0 +1,332 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com +// Original code is licensed as follows: +/* + * Copyright 2012 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "xfa/fxbarcode/pdf417/BC_PDF417Common.h" +#include "xfa/fxbarcode/pdf417/BC_PDF417ECModulusGF.h" +#include "xfa/fxbarcode/pdf417/BC_PDF417ECModulusPoly.h" +#include "xfa/fxbarcode/utils.h" + +CBC_PDF417ECModulusPoly::CBC_PDF417ECModulusPoly(CBC_PDF417ECModulusGF* field, + CFX_Int32Array& coefficients, + int32_t& e) { + if (coefficients.GetSize() == 0) { + e = BCExceptionIllegalArgument; + } + m_field = field; + int32_t coefficientsLength = coefficients.GetSize(); + if (coefficientsLength > 1 && coefficients[0] == 0) { + int32_t firstNonZero = 1; + while (firstNonZero < coefficientsLength && + coefficients[firstNonZero] == 0) { + firstNonZero++; + } + if (firstNonZero == coefficientsLength) { + m_coefficients = field->getZero()->m_coefficients; + } else { + m_coefficients.SetSize(coefficientsLength - firstNonZero); + int32_t l = 0; + for (int32_t i = firstNonZero; + i < firstNonZero + m_coefficients.GetSize(); i++) { + m_coefficients.SetAt(l, coefficients.GetAt(i)); + l++; + } + } + } else { + m_coefficients.Copy(coefficients); + } +} +CBC_PDF417ECModulusPoly::~CBC_PDF417ECModulusPoly() {} +CFX_Int32Array& CBC_PDF417ECModulusPoly::getCoefficients() { + return m_coefficients; +} +CBC_PDF417ECModulusGF* CBC_PDF417ECModulusPoly::getField() { + return m_field; +} +int32_t CBC_PDF417ECModulusPoly::getDegree() { + return m_coefficients.GetSize() - 1; +} +FX_BOOL CBC_PDF417ECModulusPoly::isZero() { + return m_coefficients[0] == 0; +} +int32_t CBC_PDF417ECModulusPoly::getCoefficient(int32_t degree) { + return m_coefficients[m_coefficients.GetSize() - 1 - degree]; +} +int32_t CBC_PDF417ECModulusPoly::evaluateAt(int32_t a) { + if (a == 0) { + return getCoefficient(0); + } + int32_t size = m_coefficients.GetSize(); + if (a == 1) { + int32_t result = 0; + for (int32_t l = 0; l < m_coefficients.GetSize(); l++) { + int32_t coefficient = m_coefficients.GetAt(l); + result = m_field->add(result, coefficient); + } + return result; + } + int32_t result = m_coefficients[0]; + for (int32_t i = 1; i < size; i++) { + result = m_field->add(m_field->multiply(a, result), m_coefficients[i]); + } + return result; +} +CBC_PDF417ECModulusPoly* CBC_PDF417ECModulusPoly::add( + CBC_PDF417ECModulusPoly* other, + int32_t& e) { + CBC_PDF417ECModulusPoly* modulusPoly = NULL; + if (isZero()) { + modulusPoly = new CBC_PDF417ECModulusPoly(other->getField(), + other->getCoefficients(), e); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + return modulusPoly; + } + if (other->isZero()) { + modulusPoly = new CBC_PDF417ECModulusPoly(m_field, m_coefficients, e); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + return modulusPoly; + } + CFX_Int32Array smallerCoefficients; + smallerCoefficients.Copy(m_coefficients); + CFX_Int32Array largerCoefficients; + largerCoefficients.Copy(other->m_coefficients); + if (smallerCoefficients.GetSize() > largerCoefficients.GetSize()) { + CFX_Int32Array temp; + temp.Copy(smallerCoefficients); + smallerCoefficients.Copy(largerCoefficients); + largerCoefficients.Copy(temp); + } + CFX_Int32Array sumDiff; + sumDiff.SetSize(largerCoefficients.GetSize()); + int32_t lengthDiff = + largerCoefficients.GetSize() - smallerCoefficients.GetSize(); + for (int32_t l = 0; l < lengthDiff; l++) { + sumDiff.SetAt(l, largerCoefficients.GetAt(l)); + } + for (int32_t i = lengthDiff; i < largerCoefficients.GetSize(); i++) { + sumDiff[i] = m_field->add(smallerCoefficients[i - lengthDiff], + largerCoefficients[i]); + } + modulusPoly = new CBC_PDF417ECModulusPoly(m_field, sumDiff, e); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + return modulusPoly; +} +CBC_PDF417ECModulusPoly* CBC_PDF417ECModulusPoly::subtract( + CBC_PDF417ECModulusPoly* other, + int32_t& e) { + CBC_PDF417ECModulusPoly* modulusPoly = NULL; + if (other->isZero()) { + modulusPoly = new CBC_PDF417ECModulusPoly(m_field, m_coefficients, e); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + return modulusPoly; + } + CBC_PDF417ECModulusPoly* poly = other->negative(e); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + modulusPoly = add(poly, e); + delete poly; + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + return modulusPoly; +} +CBC_PDF417ECModulusPoly* CBC_PDF417ECModulusPoly::multiply( + CBC_PDF417ECModulusPoly* other, + int32_t& e) { + CBC_PDF417ECModulusPoly* modulusPoly = NULL; + if (isZero() || other->isZero()) { + modulusPoly = + new CBC_PDF417ECModulusPoly(m_field->getZero()->getField(), + m_field->getZero()->getCoefficients(), e); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + return modulusPoly; + } + CFX_Int32Array aCoefficients; + aCoefficients.Copy(m_coefficients); + int32_t aLength = aCoefficients.GetSize(); + CFX_Int32Array bCoefficients; + bCoefficients.Copy(other->m_coefficients); + int32_t bLength = bCoefficients.GetSize(); + CFX_Int32Array product; + product.SetSize(aLength + bLength - 1); + for (int32_t i = 0; i < aLength; i++) { + int32_t aCoeff = aCoefficients[i]; + for (int32_t j = 0; j < bLength; j++) { + product[i + j] = m_field->add( + product[i + j], m_field->multiply(aCoeff, bCoefficients[j])); + } + } + modulusPoly = new CBC_PDF417ECModulusPoly(m_field, product, e); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + return modulusPoly; +} +CBC_PDF417ECModulusPoly* CBC_PDF417ECModulusPoly::negative(int32_t& e) { + int32_t size = m_coefficients.GetSize(); + CFX_Int32Array negativeCoefficients; + negativeCoefficients.SetSize(size); + for (int32_t i = 0; i < size; i++) { + negativeCoefficients[i] = m_field->subtract(0, m_coefficients[i]); + } + CBC_PDF417ECModulusPoly* modulusPoly = + new CBC_PDF417ECModulusPoly(m_field, negativeCoefficients, e); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + return modulusPoly; +} +CBC_PDF417ECModulusPoly* CBC_PDF417ECModulusPoly::multiply(int32_t scalar, + int32_t& e) { + CBC_PDF417ECModulusPoly* modulusPoly = NULL; + if (scalar == 0) { + modulusPoly = + new CBC_PDF417ECModulusPoly(m_field->getZero()->getField(), + m_field->getZero()->getCoefficients(), e); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + return modulusPoly; + } + if (scalar == 1) { + modulusPoly = new CBC_PDF417ECModulusPoly(m_field, m_coefficients, e); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + return modulusPoly; + } + int32_t size = m_coefficients.GetSize(); + CFX_Int32Array product; + product.SetSize(size); + for (int32_t i = 0; i < size; i++) { + product[i] = m_field->multiply(m_coefficients[i], scalar); + } + modulusPoly = new CBC_PDF417ECModulusPoly(m_field, product, e); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + return modulusPoly; +} +CBC_PDF417ECModulusPoly* CBC_PDF417ECModulusPoly::multiplyByMonomial( + int32_t degree, + int32_t coefficient, + int32_t& e) { + if (degree < 0) { + e = BCExceptionIllegalArgument; + return NULL; + } + CBC_PDF417ECModulusPoly* modulusPoly = NULL; + if (coefficient == 0) { + modulusPoly = new CBC_PDF417ECModulusPoly( + m_field->getZero()->m_field, m_field->getZero()->m_coefficients, e); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + return modulusPoly; + } + int32_t size = m_coefficients.GetSize(); + CFX_Int32Array product; + product.SetSize(size + degree); + for (int32_t i = 0; i < size; i++) { + product[i] = m_field->multiply(m_coefficients[i], coefficient); + } + modulusPoly = new CBC_PDF417ECModulusPoly(m_field, product, e); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + return modulusPoly; +} +CFX_PtrArray* CBC_PDF417ECModulusPoly::divide(CBC_PDF417ECModulusPoly* other, + int32_t& e) { + if (other->isZero()) { + e = BCExceptionDivideByZero; + return NULL; + } + CBC_PDF417ECModulusPoly* quotient = new CBC_PDF417ECModulusPoly( + m_field->getZero()->m_field, m_field->getZero()->m_coefficients, e); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + CBC_PDF417ECModulusPoly* remainder = + new CBC_PDF417ECModulusPoly(m_field, m_coefficients, e); + if (e != BCExceptionNO) { + delete quotient; + return NULL; + } + int32_t denominatorLeadingTerm = other->getCoefficient(other->getDegree()); + int32_t inverseDenominatorLeadingTerm = + m_field->inverse(denominatorLeadingTerm, e); + if (e != BCExceptionNO) { + delete quotient; + delete remainder; + return NULL; + } + while (remainder->getDegree() >= other->getDegree() && !remainder->isZero()) { + int32_t degreeDifference = remainder->getDegree() - other->getDegree(); + int32_t scale = + m_field->multiply(remainder->getCoefficient(remainder->getDegree()), + inverseDenominatorLeadingTerm); + CBC_PDF417ECModulusPoly* term = + other->multiplyByMonomial(degreeDifference, scale, e); + if (e != BCExceptionNO) { + delete quotient; + delete remainder; + return NULL; + } + CBC_PDF417ECModulusPoly* iterationQuotient = + m_field->buildMonomial(degreeDifference, scale, e); + if (e != BCExceptionNO) { + delete quotient; + delete remainder; + delete term; + return NULL; + } + CBC_PDF417ECModulusPoly* temp = quotient; + quotient = temp->add(iterationQuotient, e); + delete iterationQuotient; + delete temp; + if (e != BCExceptionNO) { + delete remainder; + return NULL; + } + temp = remainder; + remainder = temp->subtract(term, e); + delete term; + delete temp; + if (e != BCExceptionNO) { + delete quotient; + return NULL; + } + } + CFX_PtrArray* modulusPoly = new CFX_PtrArray; + modulusPoly->Add(quotient); + modulusPoly->Add(remainder); + return modulusPoly; +} +CFX_ByteString CBC_PDF417ECModulusPoly::toString() { + CFX_ByteString result; + for (int32_t degree = getDegree(); degree >= 0; degree--) { + int32_t coefficient = getCoefficient(degree); + if (coefficient != 0) { + if (coefficient < 0) { + result += " - "; + coefficient = -coefficient; + } else { + if (result.GetLength() > 0) { + result += " + "; + } + } + if (degree == 0 || coefficient != 1) { + result += coefficient; + } + if (degree != 0) { + if (degree == 1) { + result += 'x'; + } else { + result += "x^"; + result += degree; + } + } + } + } + return result; +} diff --git a/xfa/fxbarcode/pdf417/BC_PDF417ECModulusPoly.h b/xfa/fxbarcode/pdf417/BC_PDF417ECModulusPoly.h new file mode 100644 index 0000000000..2eff3ef1ce --- /dev/null +++ b/xfa/fxbarcode/pdf417/BC_PDF417ECModulusPoly.h @@ -0,0 +1,39 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef XFA_FXBARCODE_PDF417_BC_PDF417ECMODULUSPOLY_H_ +#define XFA_FXBARCODE_PDF417_BC_PDF417ECMODULUSPOLY_H_ + +class CBC_PDF417ECModulusGF; +class CBC_PDF417ECModulusPoly { + public: + CBC_PDF417ECModulusPoly(CBC_PDF417ECModulusGF* field, + CFX_Int32Array& coefficients, + int32_t& e); + virtual ~CBC_PDF417ECModulusPoly(); + CFX_Int32Array& getCoefficients(); + CBC_PDF417ECModulusGF* getField(); + int32_t getDegree(); + FX_BOOL isZero(); + int32_t getCoefficient(int32_t degree); + int32_t evaluateAt(int32_t a); + CBC_PDF417ECModulusPoly* add(CBC_PDF417ECModulusPoly* other, int32_t& e); + CBC_PDF417ECModulusPoly* subtract(CBC_PDF417ECModulusPoly* other, int32_t& e); + CBC_PDF417ECModulusPoly* multiply(CBC_PDF417ECModulusPoly* other, int32_t& e); + CBC_PDF417ECModulusPoly* negative(int32_t& e); + CBC_PDF417ECModulusPoly* multiply(int32_t scalar, int32_t& e); + CBC_PDF417ECModulusPoly* multiplyByMonomial(int32_t degree, + int32_t coefficient, + int32_t& e); + CFX_PtrArray* divide(CBC_PDF417ECModulusPoly* other, int32_t& e); + CFX_ByteString toString(); + + private: + CBC_PDF417ECModulusGF* m_field; + CFX_Int32Array m_coefficients; +}; + +#endif // XFA_FXBARCODE_PDF417_BC_PDF417ECMODULUSPOLY_H_ diff --git a/xfa/fxbarcode/pdf417/BC_PDF417ErrorCorrection.cpp b/xfa/fxbarcode/pdf417/BC_PDF417ErrorCorrection.cpp new file mode 100644 index 0000000000..0d4f2ffdb3 --- /dev/null +++ b/xfa/fxbarcode/pdf417/BC_PDF417ErrorCorrection.cpp @@ -0,0 +1,165 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com +// Original code is licensed as follows: +/* + * Copyright 2006 Jeremias Maerki in part, and ZXing Authors in part + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "xfa/fxbarcode/pdf417/BC_PDF417ErrorCorrection.h" +#include "xfa/fxbarcode/utils.h" + +int32_t CBC_PDF417ErrorCorrection::EC_COEFFICIENTS[][2500] = { + {27, 917}, + {522, 568, 723, 809}, + {237, 308, 436, 284, 646, 653, 428, 379}, + {274, 562, 232, 755, 599, 524, 801, 132, 295, 116, 442, 428, 295, 42, 176, + 65}, + {361, 575, 922, 525, 176, 586, 640, 321, 536, 742, 677, 742, 687, 284, 193, + 517, 273, 494, 263, 147, 593, 800, 571, 320, 803, 133, 231, 390, 685, 330, + 63, 410}, + {539, 422, 6, 93, 862, 771, 453, 106, 610, 287, 107, 505, 733, 877, 381, + 612, 723, 476, 462, 172, 430, 609, 858, 822, 543, 376, 511, 400, 672, 762, + 283, 184, 440, 35, 519, 31, 460, 594, 225, 535, 517, 352, 605, 158, 651, + 201, 488, 502, 648, 733, 717, 83, 404, 97, 280, 771, 840, 629, 4, 381, 843, + 623, 264, 543}, + {521, 310, 864, 547, 858, 580, 296, 379, 53, 779, 897, 444, 400, 925, 749, + 415, 822, 93, 217, 208, 928, 244, 583, 620, 246, 148, 447, 631, 292, 908, + 490, 704, 516, 258, 457, 907, 594, 723, 674, 292, 272, 96, 684, 432, 686, + 606, 860, 569, 193, 219, 129, 186, 236, 287, 192, 775, 278, 173, 40, 379, + 712, 463, 646, 776, 171, 491, 297, 763, 156, 732, 95, 270, 447, 90, 507, + 48, 228, 821, 808, 898, 784, 663, 627, 378, 382, 262, 380, 602, 754, 336, + 89, 614, 87, 432, 670, 616, 157, 374, 242, 726, 600, 269, 375, 898, 845, + 454, 354, 130, 814, 587, 804, 34, 211, 330, 539, 297, 827, 865, 37, 517, + 834, 315, 550, 86, 801, 4, 108, 539}, + {524, 894, 75, 766, 882, 857, 74, 204, 82, 586, 708, 250, 905, 786, 138, + 720, 858, 194, 311, 913, 275, 190, 375, 850, 438, 733, 194, 280, 201, 280, + 828, 757, 710, 814, 919, 89, 68, 569, 11, 204, 796, 605, 540, 913, 801, + 700, 799, 137, 439, 418, 592, 668, 353, 859, 370, 694, 325, 240, 216, 257, + 284, 549, 209, 884, 315, 70, 329, 793, 490, 274, 877, 162, 749, 812, 684, + 461, 334, 376, 849, 521, 307, 291, 803, 712, 19, 358, 399, 908, 103, 511, + 51, 8, 517, 225, 289, 470, 637, 731, 66, 255, 917, 269, 463, 830, 730, 433, + 848, 585, 136, 538, 906, 90, 2, 290, 743, 199, 655, 903, 329, 49, 802, 580, + 355, 588, 188, 462, 10, 134, 628, 320, 479, 130, 739, 71, 263, 318, 374, + 601, 192, 605, 142, 673, 687, 234, 722, 384, 177, 752, 607, 640, 455, 193, + 689, 707, 805, 641, 48, 60, 732, 621, 895, 544, 261, 852, 655, 309, 697, + 755, 756, 60, 231, 773, 434, 421, 726, 528, 503, 118, 49, 795, 32, 144, + 500, 238, 836, 394, 280, 566, 319, 9, 647, 550, 73, 914, 342, 126, 32, 681, + 331, 792, 620, 60, 609, 441, 180, 791, 893, 754, 605, 383, 228, 749, 760, + 213, 54, 297, 134, 54, 834, 299, 922, 191, 910, 532, 609, 829, 189, 20, + 167, 29, 872, 449, 83, 402, 41, 656, 505, 579, 481, 173, 404, 251, 688, 95, + 497, 555, 642, 543, 307, 159, 924, 558, 648, 55, 497, 10}, + {352, 77, 373, 504, 35, 599, 428, 207, 409, 574, 118, 498, 285, 380, 350, + 492, 197, 265, 920, 155, 914, 299, 229, 643, 294, 871, 306, 88, 87, 193, + 352, 781, 846, 75, 327, 520, 435, 543, 203, 666, 249, 346, 781, 621, 640, + 268, 794, 534, 539, 781, 408, 390, 644, 102, 476, 499, 290, 632, 545, 37, + 858, 916, 552, 41, 542, 289, 122, 272, 383, 800, 485, 98, 752, 472, 761, + 107, 784, 860, 658, 741, 290, 204, 681, 407, 855, 85, 99, 62, 482, 180, 20, + 297, 451, 593, 913, 142, 808, 684, 287, 536, 561, 76, 653, 899, 729, 567, + 744, 390, 513, 192, 516, 258, 240, 518, 794, 395, 768, 848, 51, 610, 384, + 168, 190, 826, 328, 596, 786, 303, 570, 381, 415, 641, 156, 237, 151, 429, + 531, 207, 676, 710, 89, 168, 304, 402, 40, 708, 575, 162, 864, 229, 65, + 861, 841, 512, 164, 477, 221, 92, 358, 785, 288, 357, 850, 836, 827, 736, + 707, 94, 8, 494, 114, 521, 2, 499, 851, 543, 152, 729, 771, 95, 248, 361, + 578, 323, 856, 797, 289, 51, 684, 466, 533, 820, 669, 45, 902, 452, 167, + 342, 244, 173, 35, 463, 651, 51, 699, 591, 452, 578, 37, 124, 298, 332, + 552, 43, 427, 119, 662, 777, 475, 850, 764, 364, 578, 911, 283, 711, 472, + 420, 245, 288, 594, 394, 511, 327, 589, 777, 699, 688, 43, 408, 842, 383, + 721, 521, 560, 644, 714, 559, 62, 145, 873, 663, 713, 159, 672, 729, 624, + 59, 193, 417, 158, 209, 563, 564, 343, 693, 109, 608, 563, 365, 181, 772, + 677, 310, 248, 353, 708, 410, 579, 870, 617, 841, 632, 860, 289, 536, 35, + 777, 618, 586, 424, 833, 77, 597, 346, 269, 757, 632, 695, 751, 331, 247, + 184, 45, 787, 680, 18, 66, 407, 369, 54, 492, 228, 613, 830, 922, 437, 519, + 644, 905, 789, 420, 305, 441, 207, 300, 892, 827, 141, 537, 381, 662, 513, + 56, 252, 341, 242, 797, 838, 837, 720, 224, 307, 631, 61, 87, 560, 310, + 756, 665, 397, 808, 851, 309, 473, 795, 378, 31, 647, 915, 459, 806, 590, + 731, 425, 216, 548, 249, 321, 881, 699, 535, 673, 782, 210, 815, 905, 303, + 843, 922, 281, 73, 469, 791, 660, 162, 498, 308, 155, 422, 907, 817, 187, + 62, 16, 425, 535, 336, 286, 437, 375, 273, 610, 296, 183, 923, 116, 667, + 751, 353, 62, 366, 691, 379, 687, 842, 37, 357, 720, 742, 330, 5, 39, 923, + 311, 424, 242, 749, 321, 54, 669, 316, 342, 299, 534, 105, 667, 488, 640, + 672, 576, 540, 316, 486, 721, 610, 46, 656, 447, 171, 616, 464, 190, 531, + 297, 321, 762, 752, 533, 175, 134, 14, 381, 433, 717, 45, 111, 20, 596, + 284, 736, 138, 646, 411, 877, 669, 141, 919, 45, 780, 407, 164, 332, 899, + 165, 726, 600, 325, 498, 655, 357, 752, 768, 223, 849, 647, 63, 310, 863, + 251, 366, 304, 282, 738, 675, 410, 389, 244, 31, 121, 303, 263}}; + +CBC_PDF417ErrorCorrection::CBC_PDF417ErrorCorrection() {} +CBC_PDF417ErrorCorrection::~CBC_PDF417ErrorCorrection() {} +int32_t CBC_PDF417ErrorCorrection::getErrorCorrectionCodewordCount( + int32_t errorCorrectionLevel, + int32_t& e) { + if (errorCorrectionLevel < 0 || errorCorrectionLevel > 8) { + e = BCExceptionErrorCorrectionLevelMustBeBetween0And8; + return -1; + } + return 1 << (errorCorrectionLevel + 1); +} +int32_t CBC_PDF417ErrorCorrection::getRecommendedMinimumErrorCorrectionLevel( + int32_t n, + int32_t& e) { + if (n <= 0) { + e = BCExceptionIllegalArgumentnMustBeAbove0; + return -1; + } + if (n <= 40) { + return 2; + } + if (n <= 160) { + return 3; + } + if (n <= 320) { + return 4; + } + if (n <= 863) { + return 5; + } + e = BCExceptionNoRecommendationPossible; + return -1; +} +CFX_WideString CBC_PDF417ErrorCorrection::generateErrorCorrection( + CFX_WideString dataCodewords, + int32_t errorCorrectionLevel, + int32_t& e) { + int32_t k = getErrorCorrectionCodewordCount(errorCorrectionLevel, e); + BC_EXCEPTION_CHECK_ReturnValue(e, (FX_WCHAR)' '); + FX_WCHAR* ech = FX_Alloc(FX_WCHAR, k); + FXSYS_memset(ech, 0, k * sizeof(FX_WCHAR)); + int32_t sld = dataCodewords.GetLength(); + for (int32_t i = 0; i < sld; i++) { + int32_t t1 = (dataCodewords.GetAt(i) + ech[k - 1]) % 929; + int32_t t2; + int32_t t3; + for (int32_t j = k - 1; j >= 1; j--) { + t2 = (t1 * EC_COEFFICIENTS[errorCorrectionLevel][j]) % 929; + t3 = 929 - t2; + ech[j] = (FX_WCHAR)((ech[j - 1] + t3) % 929); + } + t2 = (t1 * EC_COEFFICIENTS[errorCorrectionLevel][0]) % 929; + t3 = 929 - t2; + ech[0] = (FX_WCHAR)(t3 % 929); + } + CFX_WideString sb; + for (int32_t j = k - 1; j >= 0; j--) { + if (ech[j] != 0) { + ech[j] = (FX_WCHAR)(929 - ech[j]); + } + sb += (FX_WCHAR)ech[j]; + } + FX_Free(ech); + return sb; +} diff --git a/xfa/fxbarcode/pdf417/BC_PDF417ErrorCorrection.h b/xfa/fxbarcode/pdf417/BC_PDF417ErrorCorrection.h new file mode 100644 index 0000000000..9a2a0c63ef --- /dev/null +++ b/xfa/fxbarcode/pdf417/BC_PDF417ErrorCorrection.h @@ -0,0 +1,30 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef XFA_FXBARCODE_PDF417_BC_PDF417ERRORCORRECTION_H_ +#define XFA_FXBARCODE_PDF417_BC_PDF417ERRORCORRECTION_H_ + +#include <stdint.h> + +#include "core/include/fxcrt/fx_string.h" + +class CBC_PDF417ErrorCorrection { + public: + CBC_PDF417ErrorCorrection(); + virtual ~CBC_PDF417ErrorCorrection(); + static int32_t getErrorCorrectionCodewordCount(int32_t errorCorrectionLevel, + int32_t& e); + static int32_t getRecommendedMinimumErrorCorrectionLevel(int32_t n, + int32_t& e); + static CFX_WideString generateErrorCorrection(CFX_WideString dataCodewords, + int32_t errorCorrectionLevel, + int32_t& e); + + private: + static int32_t EC_COEFFICIENTS[][2500]; +}; + +#endif // XFA_FXBARCODE_PDF417_BC_PDF417ERRORCORRECTION_H_ diff --git a/xfa/fxbarcode/pdf417/BC_PDF417HighLevelEncoder.cpp b/xfa/fxbarcode/pdf417/BC_PDF417HighLevelEncoder.cpp new file mode 100644 index 0000000000..27c6651542 --- /dev/null +++ b/xfa/fxbarcode/pdf417/BC_PDF417HighLevelEncoder.cpp @@ -0,0 +1,427 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com +// Original code is licensed as follows: +/* + * Copyright 2006 Jeremias Maerki in part, and ZXing Authors in part + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "xfa/fxbarcode/pdf417/BC_PDF417HighLevelEncoder.h" + +#include "third_party/bigint/BigIntegerLibrary.hh" +#include "xfa/fxbarcode/BC_UtilCodingConvert.h" +#include "xfa/fxbarcode/pdf417/BC_PDF417Compaction.h" +#include "xfa/fxbarcode/utils.h" + +#define SUBMODE_ALPHA 0 +#define SUBMODE_LOWER 1 +#define SUBMODE_MIXED 2 + +int32_t CBC_PDF417HighLevelEncoder::TEXT_COMPACTION = 0; +int32_t CBC_PDF417HighLevelEncoder::BYTE_COMPACTION = 1; +int32_t CBC_PDF417HighLevelEncoder::NUMERIC_COMPACTION = 2; +int32_t CBC_PDF417HighLevelEncoder::SUBMODE_PUNCTUATION = 3; +int32_t CBC_PDF417HighLevelEncoder::LATCH_TO_TEXT = 900; +int32_t CBC_PDF417HighLevelEncoder::LATCH_TO_BYTE_PADDED = 901; +int32_t CBC_PDF417HighLevelEncoder::LATCH_TO_NUMERIC = 902; +int32_t CBC_PDF417HighLevelEncoder::SHIFT_TO_BYTE = 913; +int32_t CBC_PDF417HighLevelEncoder::LATCH_TO_BYTE = 924; +uint8_t CBC_PDF417HighLevelEncoder::TEXT_MIXED_RAW[] = { + 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 38, 13, 9, 44, 58, + 35, 45, 46, 36, 47, 43, 37, 42, 61, 94, 0, 32, 0, 0, 0}; +uint8_t CBC_PDF417HighLevelEncoder::TEXT_PUNCTUATION_RAW[] = { + 59, 60, 62, 64, 91, 92, 93, 95, 96, 126, 33, 13, 9, 44, 58, + 10, 45, 46, 36, 47, 34, 124, 42, 40, 41, 63, 123, 125, 39, 0}; +int32_t CBC_PDF417HighLevelEncoder::MIXED[128] = {0}; +int32_t CBC_PDF417HighLevelEncoder::PUNCTUATION[128] = {0}; + +void CBC_PDF417HighLevelEncoder::Initialize() { + Inverse(); +} +void CBC_PDF417HighLevelEncoder::Finalize() {} +CFX_WideString CBC_PDF417HighLevelEncoder::encodeHighLevel( + CFX_WideString wideMsg, + Compaction compaction, + int32_t& e) { + CFX_ByteString bytes; + CBC_UtilCodingConvert::UnicodeToUTF8(wideMsg, bytes); + CFX_WideString msg; + int32_t len = bytes.GetLength(); + for (int32_t i = 0; i < len; i++) { + FX_WCHAR ch = (FX_WCHAR)(bytes.GetAt(i) & 0xff); + if (ch == '?' && bytes.GetAt(i) != '?') { + e = BCExceptionCharactersOutsideISO88591Encoding; + return (FX_WCHAR*)""; + } + msg += ch; + } + CFX_ByteArray byteArr; + for (int32_t k = 0; k < bytes.GetLength(); k++) { + byteArr.Add(bytes.GetAt(k)); + } + CFX_WideString sb; + len = msg.GetLength(); + int32_t p = 0; + int32_t textSubMode = SUBMODE_ALPHA; + if (compaction == TEXT) { + encodeText(msg, p, len, sb, textSubMode); + } else if (compaction == BYTES) { + encodeBinary(&byteArr, p, byteArr.GetSize(), BYTE_COMPACTION, sb); + } else if (compaction == NUMERIC) { + sb += (FX_WCHAR)LATCH_TO_NUMERIC; + encodeNumeric(msg, p, len, sb); + } else { + int32_t encodingMode = LATCH_TO_TEXT; + while (p < len) { + int32_t n = determineConsecutiveDigitCount(msg, p); + if (n >= 13) { + sb += (FX_WCHAR)LATCH_TO_NUMERIC; + encodingMode = NUMERIC_COMPACTION; + textSubMode = SUBMODE_ALPHA; + encodeNumeric(msg, p, n, sb); + p += n; + } else { + int32_t t = determineConsecutiveTextCount(msg, p); + if (t >= 5 || n == len) { + if (encodingMode != TEXT_COMPACTION) { + sb += (FX_WCHAR)LATCH_TO_TEXT; + encodingMode = TEXT_COMPACTION; + textSubMode = SUBMODE_ALPHA; + } + textSubMode = encodeText(msg, p, t, sb, textSubMode); + p += t; + } else { + int32_t b = determineConsecutiveBinaryCount(msg, &byteArr, p, e); + BC_EXCEPTION_CHECK_ReturnValue(e, (FX_WCHAR)' '); + if (b == 0) { + b = 1; + } + if (b == 1 && encodingMode == TEXT_COMPACTION) { + encodeBinary(&byteArr, p, 1, TEXT_COMPACTION, sb); + } else { + encodeBinary(&byteArr, p, b, encodingMode, sb); + encodingMode = BYTE_COMPACTION; + textSubMode = SUBMODE_ALPHA; + } + p += b; + } + } + } + } + return sb; +} + +void CBC_PDF417HighLevelEncoder::Inverse() { + for (size_t l = 0; l < FX_ArraySize(MIXED); ++l) + MIXED[l] = -1; + + for (uint8_t i = 0; i < FX_ArraySize(TEXT_MIXED_RAW); ++i) { + uint8_t b = TEXT_MIXED_RAW[i]; + if (b != 0) + MIXED[b] = i; + } + + for (size_t l = 0; l < FX_ArraySize(PUNCTUATION); ++l) + PUNCTUATION[l] = -1; + + for (uint8_t i = 0; i < FX_ArraySize(TEXT_PUNCTUATION_RAW); ++i) { + uint8_t b = TEXT_PUNCTUATION_RAW[i]; + if (b != 0) + PUNCTUATION[b] = i; + } +} + +int32_t CBC_PDF417HighLevelEncoder::encodeText(CFX_WideString msg, + int32_t startpos, + int32_t count, + CFX_WideString& sb, + int32_t initialSubmode) { + CFX_WideString tmp; + int32_t submode = initialSubmode; + int32_t idx = 0; + while (TRUE) { + FX_WCHAR ch = msg.GetAt(startpos + idx); + switch (submode) { + case SUBMODE_ALPHA: + if (isAlphaUpper(ch)) { + if (ch == ' ') { + tmp += (FX_WCHAR)26; + } else { + tmp += (FX_WCHAR)(ch - 65); + } + } else { + if (isAlphaLower(ch)) { + submode = SUBMODE_LOWER; + tmp += (FX_WCHAR)27; + continue; + } else if (isMixed(ch)) { + submode = SUBMODE_MIXED; + tmp += (FX_WCHAR)28; + continue; + } else { + tmp += (FX_WCHAR)29; + tmp += PUNCTUATION[ch]; + break; + } + } + break; + case SUBMODE_LOWER: + if (isAlphaLower(ch)) { + if (ch == ' ') { + tmp += (FX_WCHAR)26; + } else { + tmp += (FX_WCHAR)(ch - 97); + } + } else { + if (isAlphaUpper(ch)) { + tmp += (FX_WCHAR)27; + tmp += (FX_WCHAR)(ch - 65); + break; + } else if (isMixed(ch)) { + submode = SUBMODE_MIXED; + tmp += (FX_WCHAR)28; + continue; + } else { + tmp += (FX_WCHAR)29; + tmp += PUNCTUATION[ch]; + break; + } + } + break; + case SUBMODE_MIXED: + if (isMixed(ch)) { + tmp += MIXED[ch]; + } else { + if (isAlphaUpper(ch)) { + submode = SUBMODE_ALPHA; + tmp += (FX_WCHAR)28; + continue; + } else if (isAlphaLower(ch)) { + submode = SUBMODE_LOWER; + tmp += (FX_WCHAR)27; + continue; + } else { + if (startpos + idx + 1 < count) { + FX_WCHAR next = msg.GetAt(startpos + idx + 1); + if (isPunctuation(next)) { + submode = SUBMODE_PUNCTUATION; + tmp += (FX_WCHAR)25; + continue; + } + } + tmp += (FX_WCHAR)29; + tmp += PUNCTUATION[ch]; + } + } + break; + default: + if (isPunctuation(ch)) { + tmp += PUNCTUATION[ch]; + } else { + submode = SUBMODE_ALPHA; + tmp += (FX_WCHAR)29; + continue; + } + } + idx++; + if (idx >= count) { + break; + } + } + FX_WCHAR h = 0; + int32_t len = tmp.GetLength(); + for (int32_t i = 0; i < len; i++) { + FX_BOOL odd = (i % 2) != 0; + if (odd) { + h = (FX_WCHAR)((h * 30) + tmp.GetAt(i)); + sb += h; + } else { + h = tmp.GetAt(i); + } + } + if ((len % 2) != 0) { + sb += (FX_WCHAR)((h * 30) + 29); + } + return submode; +} +void CBC_PDF417HighLevelEncoder::encodeBinary(CFX_ByteArray* bytes, + int32_t startpos, + int32_t count, + int32_t startmode, + CFX_WideString& sb) { + if (count == 1 && startmode == TEXT_COMPACTION) { + sb += (FX_WCHAR)SHIFT_TO_BYTE; + } + int32_t idx = startpos; + int32_t i = 0; + if (count >= 6) { + sb += (FX_WCHAR)LATCH_TO_BYTE; + FX_WCHAR chars[5]; + while ((startpos + count - idx) >= 6) { + int64_t t = 0; + for (i = 0; i < 6; i++) { + t <<= 8; + t += bytes->GetAt(idx + i) & 0xff; + } + for (i = 0; i < 5; i++) { + chars[i] = (FX_WCHAR)(t % 900); + t /= 900; + } + for (i = 4; i >= 0; i--) { + sb += (chars[i]); + } + idx += 6; + } + } + if (idx < startpos + count) { + sb += (FX_WCHAR)LATCH_TO_BYTE_PADDED; + } + for (i = idx; i < startpos + count; i++) { + int32_t ch = bytes->GetAt(i) & 0xff; + sb += (FX_WCHAR)ch; + } +} +void CBC_PDF417HighLevelEncoder::encodeNumeric(CFX_WideString msg, + int32_t startpos, + int32_t count, + CFX_WideString& sb) { + int32_t idx = 0; + BigInteger num900 = 900; + while (idx < count) { + CFX_WideString tmp; + int32_t len = 44 < count - idx ? 44 : count - idx; + CFX_ByteString part = + ((FX_WCHAR)'1' + msg.Mid(startpos + idx, len)).UTF8Encode(); + BigInteger bigint = stringToBigInteger(part.c_str()); + do { + int32_t c = (bigint % num900).toInt(); + tmp += (FX_WCHAR)(c); + bigint = bigint / num900; + } while (!bigint.isZero()); + for (int32_t i = tmp.GetLength() - 1; i >= 0; i--) { + sb += tmp.GetAt(i); + } + idx += len; + } +} +FX_BOOL CBC_PDF417HighLevelEncoder::isDigit(FX_WCHAR ch) { + return ch >= '0' && ch <= '9'; +} +FX_BOOL CBC_PDF417HighLevelEncoder::isAlphaUpper(FX_WCHAR ch) { + return ch == ' ' || (ch >= 'A' && ch <= 'Z'); +} +FX_BOOL CBC_PDF417HighLevelEncoder::isAlphaLower(FX_WCHAR ch) { + return ch == ' ' || (ch >= 'a' && ch <= 'z'); +} +FX_BOOL CBC_PDF417HighLevelEncoder::isMixed(FX_WCHAR ch) { + return MIXED[ch] != -1; +} +FX_BOOL CBC_PDF417HighLevelEncoder::isPunctuation(FX_WCHAR ch) { + return PUNCTUATION[ch] != -1; +} +FX_BOOL CBC_PDF417HighLevelEncoder::isText(FX_WCHAR ch) { + return ch == '\t' || ch == '\n' || ch == '\r' || (ch >= 32 && ch <= 126); +} +int32_t CBC_PDF417HighLevelEncoder::determineConsecutiveDigitCount( + CFX_WideString msg, + int32_t startpos) { + int32_t count = 0; + int32_t len = msg.GetLength(); + int32_t idx = startpos; + if (idx < len) { + FX_WCHAR ch = msg.GetAt(idx); + while (isDigit(ch) && idx < len) { + count++; + idx++; + if (idx < len) { + ch = msg.GetAt(idx); + } + } + } + return count; +} +int32_t CBC_PDF417HighLevelEncoder::determineConsecutiveTextCount( + CFX_WideString msg, + int32_t startpos) { + int32_t len = msg.GetLength(); + int32_t idx = startpos; + while (idx < len) { + FX_WCHAR ch = msg.GetAt(idx); + int32_t numericCount = 0; + while (numericCount < 13 && isDigit(ch) && idx < len) { + numericCount++; + idx++; + if (idx < len) { + ch = msg.GetAt(idx); + } + } + if (numericCount >= 13) { + return idx - startpos - numericCount; + } + if (numericCount > 0) { + continue; + } + ch = msg.GetAt(idx); + if (!isText(ch)) { + break; + } + idx++; + } + return idx - startpos; +} +int32_t CBC_PDF417HighLevelEncoder::determineConsecutiveBinaryCount( + CFX_WideString msg, + CFX_ByteArray* bytes, + int32_t startpos, + int32_t& e) { + int32_t len = msg.GetLength(); + int32_t idx = startpos; + while (idx < len) { + FX_WCHAR ch = msg.GetAt(idx); + int32_t numericCount = 0; + while (numericCount < 13 && isDigit(ch)) { + numericCount++; + int32_t i = idx + numericCount; + if (i >= len) { + break; + } + ch = msg.GetAt(i); + } + if (numericCount >= 13) { + return idx - startpos; + } + int32_t textCount = 0; + while (textCount < 5 && isText(ch)) { + textCount++; + int32_t i = idx + textCount; + if (i >= len) { + break; + } + ch = msg.GetAt(i); + } + if (textCount >= 5) { + return idx - startpos; + } + ch = msg.GetAt(idx); + if (bytes->GetAt(idx) == 63 && ch != '?') { + e = BCExceptionNonEncodableCharacterDetected; + return -1; + } + idx++; + } + return idx - startpos; +} diff --git a/xfa/fxbarcode/pdf417/BC_PDF417HighLevelEncoder.h b/xfa/fxbarcode/pdf417/BC_PDF417HighLevelEncoder.h new file mode 100644 index 0000000000..0ba01265f9 --- /dev/null +++ b/xfa/fxbarcode/pdf417/BC_PDF417HighLevelEncoder.h @@ -0,0 +1,74 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef XFA_FXBARCODE_PDF417_BC_PDF417HIGHLEVELENCODER_H_ +#define XFA_FXBARCODE_PDF417_BC_PDF417HIGHLEVELENCODER_H_ + +#include "core/include/fxcrt/fx_basic.h" +#include "core/include/fxcrt/fx_string.h" +#include "xfa/fxbarcode/pdf417/BC_PDF417Compaction.h" + +class CBC_PDF417HighLevelEncoder { + public: + static CFX_WideString encodeHighLevel(CFX_WideString msg, + Compaction compaction, + int32_t& e); + static void Inverse(); + static void Initialize(); + static void Finalize(); + + private: + static int32_t TEXT_COMPACTION; + static int32_t BYTE_COMPACTION; + static int32_t NUMERIC_COMPACTION; + static int32_t SUBMODE_PUNCTUATION; + static int32_t LATCH_TO_TEXT; + static int32_t LATCH_TO_BYTE_PADDED; + static int32_t LATCH_TO_NUMERIC; + static int32_t SHIFT_TO_BYTE; + static int32_t LATCH_TO_BYTE; + static uint8_t TEXT_MIXED_RAW[]; + static uint8_t TEXT_PUNCTUATION_RAW[]; + static int32_t MIXED[128]; + static int32_t PUNCTUATION[128]; + static int32_t encodeText(CFX_WideString msg, + int32_t startpos, + int32_t count, + CFX_WideString& sb, + int32_t initialSubmode); + static void encodeBinary(CFX_ByteArray* bytes, + int32_t startpos, + int32_t count, + int32_t startmode, + CFX_WideString& sb); + static void encodeNumeric(CFX_WideString msg, + int32_t startpos, + int32_t count, + CFX_WideString& sb); + static FX_BOOL isDigit(FX_WCHAR ch); + static FX_BOOL isAlphaUpper(FX_WCHAR ch); + static FX_BOOL isAlphaLower(FX_WCHAR ch); + static FX_BOOL isMixed(FX_WCHAR ch); + static FX_BOOL isPunctuation(FX_WCHAR ch); + static FX_BOOL isText(FX_WCHAR ch); + static int32_t determineConsecutiveDigitCount(CFX_WideString msg, + int32_t startpos); + static int32_t determineConsecutiveTextCount(CFX_WideString msg, + int32_t startpos); + static int32_t determineConsecutiveBinaryCount(CFX_WideString msg, + CFX_ByteArray* bytes, + int32_t startpos, + int32_t& e); + + friend class PDF417HighLevelEncoder_EncodeNumeric_Test; + friend class PDF417HighLevelEncoder_EncodeBinary_Test; + friend class PDF417HighLevelEncoder_EncodeText_Test; + friend class PDF417HighLevelEncoder_ConsecutiveDigitCount_Test; + friend class PDF417HighLevelEncoder_ConsecutiveTextCount_Test; + friend class PDF417HighLevelEncoder_ConsecutiveBinaryCount_Test; +}; + +#endif // XFA_FXBARCODE_PDF417_BC_PDF417HIGHLEVELENCODER_H_ diff --git a/xfa/fxbarcode/pdf417/BC_PDF417HighLevelEncoder_unittest.cpp b/xfa/fxbarcode/pdf417/BC_PDF417HighLevelEncoder_unittest.cpp new file mode 100644 index 0000000000..8e1837071d --- /dev/null +++ b/xfa/fxbarcode/pdf417/BC_PDF417HighLevelEncoder_unittest.cpp @@ -0,0 +1,231 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "core/include/fxcrt/fx_basic.h" +#include "testing/fx_string_testhelpers.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "xfa/fxbarcode/pdf417/BC_PDF417HighLevelEncoder.h" + +TEST(PDF417HighLevelEncoder, EncodeHighLevel) { + // TODO(tsepez): implement test cases. +} + +TEST(PDF417HighLevelEncoder, EncodeText) { + // TODO(tsepez): implement test cases. +} + +TEST(PDF417HighLevelEncoder, EncodeBinary) { + struct EncodeBinaryCase { + const char* input; + int offset; + int count; + int startmode; + const wchar_t* expected; + int expected_length; + } encode_binary_cases[] = { + // Empty string encodes as empty string. + {"", 0, 0, CBC_PDF417HighLevelEncoder::TEXT_COMPACTION, L"", 0}, + + // Fewer than 6 characters encodes as prefix without compaction. + {"xxxxx", 0, 5, CBC_PDF417HighLevelEncoder::TEXT_COMPACTION, + L"\x0385xxxxx", 6}, + + // 6 charcters triggerst text encoding compaction. + {"xxxxxx", 0, 6, CBC_PDF417HighLevelEncoder::TEXT_COMPACTION, + L"\u039c\u00c9\u031f\u012a\u00d2\u02d0", 6}, + + // Same result if initially in numeric compaction mode. + {"xxxxxx", 0, 6, CBC_PDF417HighLevelEncoder::NUMERIC_COMPACTION, + L"\u039c\u00c9\u031f\u012a\u00d2\u02d0", 6}, + }; + + CBC_PDF417HighLevelEncoder::Initialize(); + for (size_t i = 0; i < FX_ArraySize(encode_binary_cases); ++i) { + EncodeBinaryCase* ptr = &encode_binary_cases[i]; + CFX_ByteArray input_array; + size_t input_length = strlen(ptr->input); + input_array.SetSize(input_length); + for (size_t j = 0; j < input_length; ++j) { + input_array.SetAt(j, ptr->input[j]); + } + CFX_WideString expected(ptr->expected, ptr->expected_length); + CFX_WideString result; + CBC_PDF417HighLevelEncoder::encodeBinary( + &input_array, ptr->offset, ptr->count, ptr->startmode, result); + EXPECT_EQ(expected, result) << " for case number " << i; + } + CBC_PDF417HighLevelEncoder::Finalize(); +} + +TEST(PDF417HighLevelEncoder, EncodeNumeric) { + struct EncodeNumericCase { + const wchar_t* input; + int offset; + int count; + const wchar_t* expected; + int expected_length; + } encode_numeric_cases[] = { + // Empty string encodes as empty string. + {L"", 0, 0, L"", 0}, + + // Single 0 should encode as 10 base-900 == a. + {L"0", 0, 1, L"\x000a", 1}, + + // 800 should encode as 1800 base-900 == 2,0. + {L"800", 0, 3, L"\x0002\x0000", 2}, + + // Test longer strings and sub-strings. + {L"123456", 0, 6, L"\x0001\x015c\x0100", 3}, + {L"123456", 0, 5, L"\x007c\x02e9", 2}, + {L"123456", 1, 5, L"\x0089\x009c", 2}, + {L"123456", 2, 2, L"\x0086", 1}, + + // Up to 44 characters encodes as 15 base-900 words. + {L"00000000000000000000000000000000000000000000", 0, 44, + L"\x01b5\x006f\x02cc\x0084\x01bc\x0076\x00b3\x005c\x01f0\x034f\x01e6" + L"\x0090\x020b\x019b\x0064", + 15}, + + // 45 characters should encode as same 15 words followed by one additional + // word. + {L"000000000000000000000000000000000000000000000", 0, 45, + L"\x01b5\x006f\x02cc\x0084\x01bc\x0076\x00b3\x005c\x01f0\x034f\x01e6" + L"\x0090\x020b\x019b\x0064\x000a", + 16}, + + // 44 characters followed by 800 should encode as 15 words followed by + // 1800 base-900 == 2,0. + {L"00000000000000000000000000000000000000000000800", 0, 47, + L"\x01b5\x006f\x02cc\x0084\x01bc\x0076\x00b3\x005c\x01f0\x034f\x01e6" + L"\x0090\x020b\x019b\x0064\x0002\x0000", + 17}, + + // Even longer input. + {L"10000000000000000000000000000000000000000000000000", 0, 50, + L"\x01e0\x02f0\x036d\x02ad\x029c\x01ea\x0011\x000b\x02d6\x023c\x0108" + L"\x02bb\x0023\x02d2\x00c8\x0001\x00d3\x0064", + 18}, + }; + + CBC_PDF417HighLevelEncoder::Initialize(); + for (size_t i = 0; i < FX_ArraySize(encode_numeric_cases); ++i) { + EncodeNumericCase* ptr = &encode_numeric_cases[i]; + CFX_WideString input(ptr->input); + CFX_WideString expected(ptr->expected, ptr->expected_length); + CFX_WideString result; + CBC_PDF417HighLevelEncoder::encodeNumeric(input, ptr->offset, ptr->count, + result); + EXPECT_EQ(expected, result) << " for case number " << i; + } + CBC_PDF417HighLevelEncoder::Finalize(); +} + +TEST(PDF417HighLevelEncoder, ConsecutiveDigitCount) { + struct ConsecutiveDigitCase { + const wchar_t* input; + int offset; + int expected_count; + } consecutive_digit_cases[] = { + // Empty string contains 0 consecuitve digits. + {L"", 0, 0}, + + // Single non-digit character contains 0 consecutive digits. + {L"X", 0, 0}, + + // Leading non-digit followed by digits contains 0 consecutive. + {L"X123", 0, 0}, + + // Single digit contains 1 consecutive digit. + {L"1", 0, 1}, + + // Single digit followe by non-digit contains 1 consecutive digit. + {L"1Z", 0, 1}, + + // Test longer strings. + {L"123FOO45678", 0, 3}, + + // Test subtring starting in digits field. + {L"123FOO45678", 3, 0}, + + // Test subtring starting in non-digits field. + {L"123FOO45678", 3, 0}, + + // Test substring starting in digits field following non-digit field. + {L"123FOO45678", 6, 5}, + }; + + CBC_PDF417HighLevelEncoder::Initialize(); + for (size_t i = 0; i < FX_ArraySize(consecutive_digit_cases); ++i) { + ConsecutiveDigitCase* ptr = &consecutive_digit_cases[i]; + CFX_WideString input(ptr->input); + int actual_count = + CBC_PDF417HighLevelEncoder::determineConsecutiveDigitCount(input, + ptr->offset); + EXPECT_EQ(ptr->expected_count, actual_count) << " for case number " << i; + } + CBC_PDF417HighLevelEncoder::Finalize(); +} + +TEST(PDF417HighLevelEncoder, ConsecutiveTextCount) { + struct ConsecutiveTextCase { + const wchar_t* input; + int offset; + int expected_count; + } consecutive_text_cases[] = { + // Empty string contains 0 consecutive text characters. + {L"", 0, 0}, + + // Single text character is 1 consecutive text characters. + {L"X", 0, 1}, + + // Trailing numbers count as text characters. + {L"X123", 0, 4}, + + // Leading numbers count as text characters. + {L"123X", 0, 4}, + + // Embedded lo-value binary characters terminate text runs. + {L"ABC\x0001XXXX", 0, 3}, + + // Embedded hi-value binary characters terminate text runs. + {L"ABC\x0100XXXX", 0, 3}, + + // Text run still found after indexing past lo-value character. + {L"ABC\x0001XXXX", 4, 4}, + + // Text run still found after indexing past hi-value character. + {L"ABC\x0100XXXX", 4, 4}, + + // Leading hi-value character results in 0 consecutive characters. + {L"\x0100XXX", 0, 0}, + + // Up to 12 numbers count as text. + {L"123456789012", 0, 12}, + + // 13 or more numbers are compresssed using numeric compression, not text. + {L"1234567890123", 0, 0}, + + // Leading Text character doesn't affect the 12 character case. + {L"X123456789012", 0, 13}, + + // Leading Text character doesn't affect the 13 character case. + {L"X1234567890123", 0, 1}, + + // Jumping between numbers and letters works properly. + {L"XXX121XXX12345678901234", 0, 9}, + }; + + CBC_PDF417HighLevelEncoder::Initialize(); + for (size_t i = 0; i < FX_ArraySize(consecutive_text_cases); ++i) { + ConsecutiveTextCase* ptr = &consecutive_text_cases[i]; + CFX_WideString input(ptr->input); + int actual_count = + CBC_PDF417HighLevelEncoder::determineConsecutiveTextCount(input, + ptr->offset); + EXPECT_EQ(ptr->expected_count, actual_count) << " for case number " << i; + } + CBC_PDF417HighLevelEncoder::Finalize(); +} + +TEST(PDF417HighLevelEncoder, ConsecutiveBinaryCount) {} diff --git a/xfa/fxbarcode/pdf417/BC_PDF417Reader.cpp b/xfa/fxbarcode/pdf417/BC_PDF417Reader.cpp new file mode 100644 index 0000000000..4d953e006a --- /dev/null +++ b/xfa/fxbarcode/pdf417/BC_PDF417Reader.cpp @@ -0,0 +1,149 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com +// Original code is licensed as follows: +/* + * Copyright 2009 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <limits> + +#include "xfa/fxbarcode/BC_BinaryBitmap.h" +#include "xfa/fxbarcode/BC_BinaryBitmap.h" +#include "xfa/fxbarcode/BC_DecoderResult.h" +#include "xfa/fxbarcode/BC_Reader.h" +#include "xfa/fxbarcode/BC_ResultPoint.h" +#include "xfa/fxbarcode/common/BC_CommonBitArray.h" +#include "xfa/fxbarcode/common/BC_CommonBitMatrix.h" +#include "xfa/fxbarcode/common/BC_CommonBitMatrix.h" +#include "xfa/fxbarcode/common/BC_CommonDecoderResult.h" +#include "xfa/fxbarcode/pdf417/BC_PDF417BarcodeMetadata.h" +#include "xfa/fxbarcode/pdf417/BC_PDF417BarcodeValue.h" +#include "xfa/fxbarcode/pdf417/BC_PDF417BoundingBox.h" +#include "xfa/fxbarcode/pdf417/BC_PDF417Codeword.h" +#include "xfa/fxbarcode/pdf417/BC_PDF417CodewordDecoder.h" +#include "xfa/fxbarcode/pdf417/BC_PDF417Common.h" +#include "xfa/fxbarcode/pdf417/BC_PDF417DecodedBitStreamParser.h" +#include "xfa/fxbarcode/pdf417/BC_PDF417DecodedBitStreamParser.h" +#include "xfa/fxbarcode/pdf417/BC_PDF417DecodedBitStreamParser.h" +#include "xfa/fxbarcode/pdf417/BC_PDF417DetectionResult.h" +#include "xfa/fxbarcode/pdf417/BC_PDF417DetectionResultColumn.h" +#include "xfa/fxbarcode/pdf417/BC_PDF417DetectionResultRowIndicatorColumn.h" +#include "xfa/fxbarcode/pdf417/BC_PDF417Detector.h" +#include "xfa/fxbarcode/pdf417/BC_PDF417DetectorResult.h" +#include "xfa/fxbarcode/pdf417/BC_PDF417DetectorResult.h" +#include "xfa/fxbarcode/pdf417/BC_PDF417ECErrorCorrection.h" +#include "xfa/fxbarcode/pdf417/BC_PDF417ECModulusGF.h" +#include "xfa/fxbarcode/pdf417/BC_PDF417ECModulusPoly.h" +#include "xfa/fxbarcode/pdf417/BC_PDF417Reader.h" +#include "xfa/fxbarcode/pdf417/BC_PDF417ScanningDecoder.h" +#include "xfa/fxbarcode/utils.h" + +CBC_PDF417Reader::CBC_PDF417Reader() {} +CBC_PDF417Reader::~CBC_PDF417Reader() {} + +CFX_ByteString CBC_PDF417Reader::Decode(CBC_BinaryBitmap* image, int32_t& e) { + return Decode(image, 0, e); +} +CFX_ByteString CBC_PDF417Reader::Decode(CBC_BinaryBitmap* image, + FX_BOOL multiple, + int32_t hints, + int32_t& e) { + CFX_ByteString results; + CBC_PDF417DetectorResult* detectorResult = + CBC_Detector::detect(image, hints, multiple, e); + BC_EXCEPTION_CHECK_ReturnValue(e, ""); + for (int32_t i = 0; i < detectorResult->getPoints()->GetSize(); i++) { + CFX_PtrArray* points = (CFX_PtrArray*)detectorResult->getPoints()->GetAt(i); + CBC_CommonDecoderResult* ResultTemp = CBC_PDF417ScanningDecoder::decode( + detectorResult->getBits(), (CBC_ResultPoint*)points->GetAt(4), + (CBC_ResultPoint*)points->GetAt(5), (CBC_ResultPoint*)points->GetAt(6), + (CBC_ResultPoint*)points->GetAt(7), getMinCodewordWidth(*points), + getMaxCodewordWidth(*points), e); + if (ResultTemp == NULL) { + delete detectorResult; + e = BCExceptiontNotFoundInstance; + return ""; + } + results += ResultTemp->GetText(); + delete ResultTemp; + } + delete detectorResult; + return results; +} +CFX_ByteString CBC_PDF417Reader::Decode(CBC_BinaryBitmap* image, + int32_t hints, + int32_t& e) { + CFX_ByteString bs = Decode(image, FALSE, 0, e); + BC_EXCEPTION_CHECK_ReturnValue(e, ""); + return bs; +} +int32_t CBC_PDF417Reader::getMaxWidth(CBC_ResultPoint* p1, + CBC_ResultPoint* p2) { + if (p1 == NULL || p2 == NULL) { + return 0; + } + return (int32_t)FXSYS_fabs(p1->GetX() - p2->GetX()); +} +int32_t CBC_PDF417Reader::getMinWidth(CBC_ResultPoint* p1, + CBC_ResultPoint* p2) { + if (!p1 || !p2) + return std::numeric_limits<int32_t>::max(); + return (int32_t)FXSYS_fabs(p1->GetX() - p2->GetX()); +} +int32_t CBC_PDF417Reader::getMaxCodewordWidth(CFX_PtrArray& p) { + int32_t a = + getMaxWidth((CBC_ResultPoint*)p.GetAt(6), (CBC_ResultPoint*)p.GetAt(2)) * + CBC_PDF417Common::MODULES_IN_CODEWORD / + CBC_PDF417Common::MODULES_IN_STOP_PATTERN; + int32_t b = + getMaxWidth((CBC_ResultPoint*)p.GetAt(7), (CBC_ResultPoint*)p.GetAt(3)) * + CBC_PDF417Common::MODULES_IN_CODEWORD / + CBC_PDF417Common::MODULES_IN_STOP_PATTERN; + int32_t c = getMaxWidth((CBC_ResultPoint*)p.GetAt(0), + (CBC_ResultPoint*)p.GetAt(4)) < a + ? getMaxWidth((CBC_ResultPoint*)p.GetAt(0), + (CBC_ResultPoint*)p.GetAt(4)) + : a; + int32_t d = getMaxWidth((CBC_ResultPoint*)p.GetAt(1), + (CBC_ResultPoint*)p.GetAt(5)) < b + ? getMaxWidth((CBC_ResultPoint*)p.GetAt(1), + (CBC_ResultPoint*)p.GetAt(5)) + : b; + return c < d ? c : d; +} +int32_t CBC_PDF417Reader::getMinCodewordWidth(CFX_PtrArray& p) { + int32_t a = + getMinWidth((CBC_ResultPoint*)p.GetAt(6), (CBC_ResultPoint*)p.GetAt(2)) * + CBC_PDF417Common::MODULES_IN_CODEWORD / + CBC_PDF417Common::MODULES_IN_STOP_PATTERN; + int32_t b = + getMinWidth((CBC_ResultPoint*)p.GetAt(7), (CBC_ResultPoint*)p.GetAt(3)) * + CBC_PDF417Common::MODULES_IN_CODEWORD / + CBC_PDF417Common::MODULES_IN_STOP_PATTERN; + int32_t c = getMinWidth((CBC_ResultPoint*)p.GetAt(0), + (CBC_ResultPoint*)p.GetAt(4)) < a + ? getMinWidth((CBC_ResultPoint*)p.GetAt(0), + (CBC_ResultPoint*)p.GetAt(4)) + : a; + int32_t d = getMinWidth((CBC_ResultPoint*)p.GetAt(1), + (CBC_ResultPoint*)p.GetAt(5)) < b + ? getMinWidth((CBC_ResultPoint*)p.GetAt(1), + (CBC_ResultPoint*)p.GetAt(5)) + : b; + return c < d ? c : d; +} diff --git a/xfa/fxbarcode/pdf417/BC_PDF417Reader.h b/xfa/fxbarcode/pdf417/BC_PDF417Reader.h new file mode 100644 index 0000000000..2a5c39bae2 --- /dev/null +++ b/xfa/fxbarcode/pdf417/BC_PDF417Reader.h @@ -0,0 +1,31 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef XFA_FXBARCODE_PDF417_BC_PDF417READER_H_ +#define XFA_FXBARCODE_PDF417_BC_PDF417READER_H_ + +class CBC_BinaryBitmap; +class CBC_ResultPoint; +class CBC_PDF417Reader; +class CBC_PDF417Reader : public CBC_Reader { + public: + CBC_PDF417Reader(); + virtual ~CBC_PDF417Reader(); + CFX_ByteString Decode(CBC_BinaryBitmap* image, int32_t& e); + CFX_ByteString Decode(CBC_BinaryBitmap* image, + FX_BOOL multiple, + int32_t hints, + int32_t& e); + CFX_ByteString Decode(CBC_BinaryBitmap* image, int32_t hints, int32_t& e); + + private: + static int32_t getMaxWidth(CBC_ResultPoint* p1, CBC_ResultPoint* p2); + static int32_t getMinWidth(CBC_ResultPoint* p1, CBC_ResultPoint* p2); + static int32_t getMaxCodewordWidth(CFX_PtrArray& p); + static int32_t getMinCodewordWidth(CFX_PtrArray& p); +}; + +#endif // XFA_FXBARCODE_PDF417_BC_PDF417READER_H_ diff --git a/xfa/fxbarcode/pdf417/BC_PDF417ResultMetadata.cpp b/xfa/fxbarcode/pdf417/BC_PDF417ResultMetadata.cpp new file mode 100644 index 0000000000..083d63e2d2 --- /dev/null +++ b/xfa/fxbarcode/pdf417/BC_PDF417ResultMetadata.cpp @@ -0,0 +1,50 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com +// Original code is licensed as follows: +/* + * Copyright 2013 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "xfa/fxbarcode/pdf417/BC_PDF417ResultMetadata.h" + +CBC_PDF417ResultMetadata::CBC_PDF417ResultMetadata() {} +CBC_PDF417ResultMetadata::~CBC_PDF417ResultMetadata() {} +int32_t CBC_PDF417ResultMetadata::getSegmentIndex() { + return m_segmentIndex; +} +void CBC_PDF417ResultMetadata::setSegmentIndex(int32_t segmentIndex) { + m_segmentIndex = segmentIndex; +} +CFX_ByteString CBC_PDF417ResultMetadata::getFileId() { + return m_fileId; +} +void CBC_PDF417ResultMetadata::setFileId(CFX_ByteString fileId) { + m_fileId = fileId; +} +CFX_Int32Array& CBC_PDF417ResultMetadata::getOptionalData() { + return m_optionalData; +} +void CBC_PDF417ResultMetadata::setOptionalData(CFX_Int32Array& optionalData) { + m_optionalData.Copy(optionalData); +} +FX_BOOL CBC_PDF417ResultMetadata::isLastSegment() { + return m_lastSegment; +} +void CBC_PDF417ResultMetadata::setLastSegment(FX_BOOL lastSegment) { + m_lastSegment = lastSegment; +} diff --git a/xfa/fxbarcode/pdf417/BC_PDF417ResultMetadata.h b/xfa/fxbarcode/pdf417/BC_PDF417ResultMetadata.h new file mode 100644 index 0000000000..8e25bdbf43 --- /dev/null +++ b/xfa/fxbarcode/pdf417/BC_PDF417ResultMetadata.h @@ -0,0 +1,32 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef XFA_FXBARCODE_PDF417_BC_PDF417RESULTMETADATA_H_ +#define XFA_FXBARCODE_PDF417_BC_PDF417RESULTMETADATA_H_ + +#include "core/include/fxcrt/fx_basic.h" + +class CBC_PDF417ResultMetadata { + public: + CBC_PDF417ResultMetadata(); + virtual ~CBC_PDF417ResultMetadata(); + int32_t getSegmentIndex(); + void setSegmentIndex(int32_t segmentIndex); + CFX_ByteString getFileId(); + void setFileId(CFX_ByteString fileId); + CFX_Int32Array& getOptionalData(); + void setOptionalData(CFX_Int32Array& optionalData); + FX_BOOL isLastSegment(); + void setLastSegment(FX_BOOL lastSegment); + + private: + int32_t m_segmentIndex; + CFX_ByteString m_fileId; + CFX_Int32Array m_optionalData; + FX_BOOL m_lastSegment; +}; + +#endif // XFA_FXBARCODE_PDF417_BC_PDF417RESULTMETADATA_H_ diff --git a/xfa/fxbarcode/pdf417/BC_PDF417ScanningDecoder.cpp b/xfa/fxbarcode/pdf417/BC_PDF417ScanningDecoder.cpp new file mode 100644 index 0000000000..6ae68d72f3 --- /dev/null +++ b/xfa/fxbarcode/pdf417/BC_PDF417ScanningDecoder.cpp @@ -0,0 +1,752 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com +// Original code is licensed as follows: +/* + * Copyright 2013 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "xfa/fxbarcode/BC_DecoderResult.h" +#include "xfa/fxbarcode/BC_ResultPoint.h" +#include "xfa/fxbarcode/common/BC_CommonBitMatrix.h" +#include "xfa/fxbarcode/pdf417/BC_PDF417BarcodeMetadata.h" +#include "xfa/fxbarcode/pdf417/BC_PDF417BarcodeValue.h" +#include "xfa/fxbarcode/pdf417/BC_PDF417BoundingBox.h" +#include "xfa/fxbarcode/pdf417/BC_PDF417Codeword.h" +#include "xfa/fxbarcode/pdf417/BC_PDF417CodewordDecoder.h" +#include "xfa/fxbarcode/pdf417/BC_PDF417Common.h" +#include "xfa/fxbarcode/pdf417/BC_PDF417DecodedBitStreamParser.h" +#include "xfa/fxbarcode/pdf417/BC_PDF417DecodedBitStreamParser.h" +#include "xfa/fxbarcode/pdf417/BC_PDF417DecodedBitStreamParser.h" +#include "xfa/fxbarcode/pdf417/BC_PDF417DetectionResult.h" +#include "xfa/fxbarcode/pdf417/BC_PDF417DetectionResultColumn.h" +#include "xfa/fxbarcode/pdf417/BC_PDF417DetectionResultRowIndicatorColumn.h" +#include "xfa/fxbarcode/pdf417/BC_PDF417ECErrorCorrection.h" +#include "xfa/fxbarcode/pdf417/BC_PDF417ECModulusGF.h" +#include "xfa/fxbarcode/pdf417/BC_PDF417ECModulusPoly.h" +#include "xfa/fxbarcode/pdf417/BC_PDF417ScanningDecoder.h" +#include "xfa/fxbarcode/utils.h" + +int32_t CBC_PDF417ScanningDecoder::CODEWORD_SKEW_SIZE = 2; +int32_t CBC_PDF417ScanningDecoder::MAX_ERRORS = 3; +int32_t CBC_PDF417ScanningDecoder::MAX_EC_CODEWORDS = 512; +CBC_PDF417ECErrorCorrection* CBC_PDF417ScanningDecoder::errorCorrection = NULL; + +CBC_PDF417ScanningDecoder::CBC_PDF417ScanningDecoder() {} +CBC_PDF417ScanningDecoder::~CBC_PDF417ScanningDecoder() {} +void CBC_PDF417ScanningDecoder::Initialize() { + errorCorrection = new CBC_PDF417ECErrorCorrection; +} +void CBC_PDF417ScanningDecoder::Finalize() { + delete errorCorrection; +} +CBC_CommonDecoderResult* CBC_PDF417ScanningDecoder::decode( + CBC_CommonBitMatrix* image, + CBC_ResultPoint* imageTopLeft, + CBC_ResultPoint* imageBottomLeft, + CBC_ResultPoint* imageTopRight, + CBC_ResultPoint* imageBottomRight, + int32_t minCodewordWidth, + int32_t maxCodewordWidth, + int32_t& e) { + CBC_BoundingBox* boundingBox = new CBC_BoundingBox( + image, imageTopLeft, imageBottomLeft, imageTopRight, imageBottomRight, e); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + CBC_DetectionResultRowIndicatorColumn* leftRowIndicatorColumn = NULL; + CBC_DetectionResultRowIndicatorColumn* rightRowIndicatorColumn = NULL; + CBC_DetectionResult* detectionResult = NULL; + for (int32_t i = 0; i < 2; i++) { + if (imageTopLeft) { + leftRowIndicatorColumn = + getRowIndicatorColumn(image, boundingBox, *imageTopLeft, TRUE, + minCodewordWidth, maxCodewordWidth); + } + if (imageTopRight) { + rightRowIndicatorColumn = + getRowIndicatorColumn(image, boundingBox, *imageTopRight, FALSE, + minCodewordWidth, maxCodewordWidth); + } + detectionResult = merge(leftRowIndicatorColumn, rightRowIndicatorColumn, e); + if (e != BCExceptionNO) { + e = BCExceptiontNotFoundInstance; + delete leftRowIndicatorColumn; + delete rightRowIndicatorColumn; + delete boundingBox; + return NULL; + } + if (i == 0 && (detectionResult->getBoundingBox()->getMinY() < + boundingBox->getMinY() || + detectionResult->getBoundingBox()->getMaxY() > + boundingBox->getMaxY())) { + delete boundingBox; + boundingBox = detectionResult->getBoundingBox(); + } else { + detectionResult->setBoundingBox(boundingBox); + break; + } + } + int32_t maxBarcodeColumn = detectionResult->getBarcodeColumnCount() + 1; + detectionResult->setDetectionResultColumn(0, leftRowIndicatorColumn); + detectionResult->setDetectionResultColumn(maxBarcodeColumn, + rightRowIndicatorColumn); + FX_BOOL leftToRight = leftRowIndicatorColumn != NULL; + for (int32_t barcodeColumnCount = 1; barcodeColumnCount <= maxBarcodeColumn; + barcodeColumnCount++) { + int32_t barcodeColumn = leftToRight ? barcodeColumnCount + : maxBarcodeColumn - barcodeColumnCount; + if (detectionResult->getDetectionResultColumn(barcodeColumn)) { + continue; + } + CBC_DetectionResultColumn* detectionResultColumn = NULL; + if (barcodeColumn == 0 || barcodeColumn == maxBarcodeColumn) { + detectionResultColumn = new CBC_DetectionResultRowIndicatorColumn( + boundingBox, barcodeColumn == 0); + } else { + detectionResultColumn = new CBC_DetectionResultColumn(boundingBox); + } + detectionResult->setDetectionResultColumn(barcodeColumn, + detectionResultColumn); + int32_t startColumn = -1; + int32_t previousStartColumn = startColumn; + for (int32_t imageRow = boundingBox->getMinY(); + imageRow <= boundingBox->getMaxY(); imageRow++) { + startColumn = + getStartColumn(detectionResult, barcodeColumn, imageRow, leftToRight); + if (startColumn < 0 || startColumn > boundingBox->getMaxX()) { + if (previousStartColumn == -1) { + continue; + } + startColumn = previousStartColumn; + } + CBC_Codeword* codeword = detectCodeword( + image, boundingBox->getMinX(), boundingBox->getMaxX(), leftToRight, + startColumn, imageRow, minCodewordWidth, maxCodewordWidth); + if (codeword) { + detectionResultColumn->setCodeword(imageRow, codeword); + previousStartColumn = startColumn; + minCodewordWidth = minCodewordWidth < codeword->getWidth() + ? minCodewordWidth + : codeword->getWidth(); + maxCodewordWidth = maxCodewordWidth > codeword->getWidth() + ? maxCodewordWidth + : codeword->getWidth(); + } + } + } + CBC_CommonDecoderResult* decoderresult = + createDecoderResult(detectionResult, e); + if (e != BCExceptionNO) { + delete detectionResult; + return NULL; + } + return decoderresult; +} +CFX_ByteString CBC_PDF417ScanningDecoder::toString( + CFX_PtrArray* barcodeMatrix) { + CFX_ByteString result; + for (int32_t row = 0; row < barcodeMatrix->GetSize(); row++) { + result += row; + int32_t l = 0; + for (; l < ((CFX_PtrArray*)barcodeMatrix->GetAt(row))->GetSize(); l++) { + CBC_BarcodeValue* barcodeValue = + (CBC_BarcodeValue*)((CFX_PtrArray*)barcodeMatrix->GetAt(row)) + ->GetAt(l); + if (barcodeValue->getValue()->GetSize() == 0) { + result += ""; + } else { + result += barcodeValue->getValue()->GetAt(0); + result += + barcodeValue->getConfidence(barcodeValue->getValue()->GetAt(0)); + } + } + } + return result; +} +CBC_DetectionResult* CBC_PDF417ScanningDecoder::merge( + CBC_DetectionResultRowIndicatorColumn* leftRowIndicatorColumn, + CBC_DetectionResultRowIndicatorColumn* rightRowIndicatorColumn, + int32_t& e) { + if (leftRowIndicatorColumn == NULL && rightRowIndicatorColumn == NULL) { + e = BCExceptionIllegalArgument; + return NULL; + } + CBC_BarcodeMetadata* barcodeMetadata = + getBarcodeMetadata(leftRowIndicatorColumn, rightRowIndicatorColumn); + if (barcodeMetadata == NULL) { + e = BCExceptionCannotMetadata; + return NULL; + } + CBC_BoundingBox* leftboundingBox = + adjustBoundingBox(leftRowIndicatorColumn, e); + if (e != BCExceptionNO) { + delete barcodeMetadata; + return NULL; + } + CBC_BoundingBox* rightboundingBox = + adjustBoundingBox(rightRowIndicatorColumn, e); + if (e != BCExceptionNO) { + delete barcodeMetadata; + return NULL; + } + CBC_BoundingBox* boundingBox = + CBC_BoundingBox::merge(leftboundingBox, rightboundingBox, e); + if (e != BCExceptionNO) { + delete barcodeMetadata; + return NULL; + } + CBC_DetectionResult* detectionresult = + new CBC_DetectionResult(barcodeMetadata, boundingBox); + return detectionresult; +} +CBC_BoundingBox* CBC_PDF417ScanningDecoder::adjustBoundingBox( + CBC_DetectionResultRowIndicatorColumn* rowIndicatorColumn, + int32_t& e) { + if (rowIndicatorColumn == NULL) { + return NULL; + } + CFX_Int32Array* rowHeights = rowIndicatorColumn->getRowHeights(e); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + int32_t maxRowHeight = getMax(*rowHeights); + int32_t missingStartRows = 0; + for (int32_t i = 0; i < rowHeights->GetSize(); i++) { + int32_t rowHeight = rowHeights->GetAt(i); + missingStartRows += maxRowHeight - rowHeight; + if (rowHeight > 0) { + break; + } + } + CFX_PtrArray* codewords = rowIndicatorColumn->getCodewords(); + for (int32_t row = 0; missingStartRows > 0 && codewords->GetAt(row) == NULL; + row++) { + missingStartRows--; + } + int32_t missingEndRows = 0; + for (int32_t row1 = rowHeights->GetSize() - 1; row1 >= 0; row1--) { + missingEndRows += maxRowHeight - rowHeights->GetAt(row1); + if (rowHeights->GetAt(row1) > 0) { + break; + } + } + for (int32_t row2 = codewords->GetSize() - 1; + missingEndRows > 0 && codewords->GetAt(row2) == NULL; row2--) { + missingEndRows--; + } + CBC_BoundingBox* boundingBox = + rowIndicatorColumn->getBoundingBox()->addMissingRows( + missingStartRows, missingEndRows, rowIndicatorColumn->isLeft(), e); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + return boundingBox; +} +int32_t CBC_PDF417ScanningDecoder::getMax(CFX_Int32Array& values) { + int32_t maxValue = -1; + for (int32_t i = 0; i < values.GetSize(); i++) { + int32_t value = values.GetAt(i); + maxValue = maxValue > value ? maxValue : value; + } + return maxValue; +} +CBC_BarcodeMetadata* CBC_PDF417ScanningDecoder::getBarcodeMetadata( + CBC_DetectionResultRowIndicatorColumn* leftRowIndicatorColumn, + CBC_DetectionResultRowIndicatorColumn* rightRowIndicatorColumn) { + CBC_BarcodeMetadata* leftBarcodeMetadata = NULL; + CBC_BarcodeMetadata* rightBarcodeMetadata = NULL; + if (leftRowIndicatorColumn == NULL || + (leftBarcodeMetadata = leftRowIndicatorColumn->getBarcodeMetadata()) == + NULL) { + return rightRowIndicatorColumn == NULL + ? NULL + : rightRowIndicatorColumn->getBarcodeMetadata(); + } + if (rightRowIndicatorColumn == NULL || + (rightBarcodeMetadata = rightRowIndicatorColumn->getBarcodeMetadata()) == + NULL) { + return leftRowIndicatorColumn == NULL + ? NULL + : leftRowIndicatorColumn->getBarcodeMetadata(); + } + if (leftBarcodeMetadata->getColumnCount() != + rightBarcodeMetadata->getColumnCount() && + leftBarcodeMetadata->getErrorCorrectionLevel() != + rightBarcodeMetadata->getErrorCorrectionLevel() && + leftBarcodeMetadata->getRowCount() != + rightBarcodeMetadata->getRowCount()) { + delete leftBarcodeMetadata; + delete rightBarcodeMetadata; + return NULL; + } + delete rightBarcodeMetadata; + return leftBarcodeMetadata; +} +CBC_DetectionResultRowIndicatorColumn* +CBC_PDF417ScanningDecoder::getRowIndicatorColumn(CBC_CommonBitMatrix* image, + CBC_BoundingBox* boundingBox, + CBC_ResultPoint startPoint, + FX_BOOL leftToRight, + int32_t minCodewordWidth, + int32_t maxCodewordWidth) { + CBC_DetectionResultRowIndicatorColumn* rowIndicatorColumn = + new CBC_DetectionResultRowIndicatorColumn(boundingBox, leftToRight); + for (int32_t i = 0; i < 2; i++) { + int32_t increment = i == 0 ? 1 : -1; + int32_t startColumn = (int32_t)startPoint.GetX(); + for (int32_t imageRow = (int32_t)startPoint.GetY(); + imageRow <= boundingBox->getMaxY() && + imageRow >= boundingBox->getMinY(); + imageRow += increment) { + CBC_Codeword* codeword = + detectCodeword(image, 0, image->GetWidth(), leftToRight, startColumn, + imageRow, minCodewordWidth, maxCodewordWidth); + if (codeword) { + rowIndicatorColumn->setCodeword(imageRow, codeword); + if (leftToRight) { + startColumn = codeword->getStartX(); + } else { + startColumn = codeword->getEndX(); + } + } + } + } + return rowIndicatorColumn; +} +void CBC_PDF417ScanningDecoder::adjustCodewordCount( + CBC_DetectionResult* detectionResult, + CFX_PtrArray* barcodeMatrix, + int32_t& e) { + CFX_Int32Array* numberOfCodewords = + ((CBC_BarcodeValue*)((CFX_PtrArray*)barcodeMatrix->GetAt(0))->GetAt(1)) + ->getValue(); + int32_t calculatedNumberOfCodewords = + detectionResult->getBarcodeColumnCount() * + detectionResult->getBarcodeRowCount() - + getNumberOfECCodeWords(detectionResult->getBarcodeECLevel()); + if (numberOfCodewords->GetSize() == 0) { + if (calculatedNumberOfCodewords < 1 || + calculatedNumberOfCodewords > + CBC_PDF417Common::MAX_CODEWORDS_IN_BARCODE) { + e = BCExceptiontNotFoundInstance; + delete numberOfCodewords; + BC_EXCEPTION_CHECK_ReturnVoid(e); + } + ((CBC_BarcodeValue*)((CFX_PtrArray*)barcodeMatrix->GetAt(0))->GetAt(1)) + ->setValue(calculatedNumberOfCodewords); + } else if (numberOfCodewords->GetAt(0) != calculatedNumberOfCodewords) { + ((CBC_BarcodeValue*)((CFX_PtrArray*)barcodeMatrix->GetAt(0))->GetAt(1)) + ->setValue(calculatedNumberOfCodewords); + } + delete numberOfCodewords; +} +CBC_CommonDecoderResult* CBC_PDF417ScanningDecoder::createDecoderResult( + CBC_DetectionResult* detectionResult, + int32_t& e) { + CFX_PtrArray* barcodeMatrix = createBarcodeMatrix(detectionResult); + adjustCodewordCount(detectionResult, barcodeMatrix, e); + if (e != BCExceptionNO) { + for (int32_t i = 0; i < barcodeMatrix->GetSize(); i++) { + CFX_PtrArray* temp = (CFX_PtrArray*)barcodeMatrix->GetAt(i); + for (int32_t j = 0; j < temp->GetSize(); j++) { + delete (CBC_BarcodeValue*)temp->GetAt(j); + } + temp->RemoveAll(); + delete temp; + } + barcodeMatrix->RemoveAll(); + delete barcodeMatrix; + return NULL; + } + CFX_Int32Array erasures; + CFX_Int32Array codewords; + codewords.SetSize(detectionResult->getBarcodeRowCount() * + detectionResult->getBarcodeColumnCount()); + CFX_PtrArray ambiguousIndexValuesList; + CFX_Int32Array ambiguousIndexesList; + for (int32_t row = 0; row < detectionResult->getBarcodeRowCount(); row++) { + for (int32_t l = 0; l < detectionResult->getBarcodeColumnCount(); l++) { + CFX_Int32Array* values = + ((CBC_BarcodeValue*)((CFX_PtrArray*)barcodeMatrix->GetAt(row)) + ->GetAt(l + 1)) + ->getValue(); + int32_t codewordIndex = + row * detectionResult->getBarcodeColumnCount() + l; + if (values->GetSize() == 0) { + erasures.Add(codewordIndex); + } else if (values->GetSize() == 1) { + codewords[codewordIndex] = values->GetAt(0); + } else { + ambiguousIndexesList.Add(codewordIndex); + ambiguousIndexValuesList.Add(values); + } + } + } + CFX_PtrArray ambiguousIndexValues; + ambiguousIndexValues.SetSize(ambiguousIndexValuesList.GetSize()); + for (int32_t i = 0; i < ambiguousIndexValues.GetSize(); i++) { + ambiguousIndexValues.SetAt(i, ambiguousIndexValuesList.GetAt(i)); + } + for (int32_t l = 0; l < barcodeMatrix->GetSize(); l++) { + CFX_PtrArray* temp = (CFX_PtrArray*)barcodeMatrix->GetAt(l); + for (int32_t j = 0; j < temp->GetSize(); j++) { + delete (CBC_BarcodeValue*)temp->GetAt(j); + } + temp->RemoveAll(); + delete temp; + } + barcodeMatrix->RemoveAll(); + delete barcodeMatrix; + CBC_CommonDecoderResult* decoderResult = + createDecoderResultFromAmbiguousValues( + detectionResult->getBarcodeECLevel(), codewords, erasures, + ambiguousIndexesList, ambiguousIndexValues, e); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + return decoderResult; +} +CBC_CommonDecoderResult* +CBC_PDF417ScanningDecoder::createDecoderResultFromAmbiguousValues( + int32_t ecLevel, + CFX_Int32Array& codewords, + CFX_Int32Array& erasureArray, + CFX_Int32Array& ambiguousIndexes, + CFX_PtrArray& ambiguousIndexValues, + int32_t& e) { + CFX_Int32Array ambiguousIndexCount; + ambiguousIndexCount.SetSize(ambiguousIndexes.GetSize()); + int32_t tries = 100; + while (tries-- > 0) { + for (int32_t l = 0; l < ambiguousIndexCount.GetSize(); l++) { + codewords[ambiguousIndexes[l]] = + ((CFX_Int32Array*)ambiguousIndexValues.GetAt(l)) + ->GetAt(ambiguousIndexCount[l]); + } + CBC_CommonDecoderResult* decoderResult = + decodeCodewords(codewords, ecLevel, erasureArray, e); + if (e != BCExceptionNO) { + e = BCExceptionNO; + continue; + } else { + return decoderResult; + } + if (ambiguousIndexCount.GetSize() == 0) { + e = BCExceptionChecksumInstance; + return NULL; + } + for (int32_t i = 0; i < ambiguousIndexCount.GetSize(); i++) { + if (ambiguousIndexCount[i] < + ((CFX_Int32Array*)(ambiguousIndexValues.GetAt(i)))->GetSize() - 1) { + ambiguousIndexCount[i]++; + break; + } else { + ambiguousIndexCount[i] = 0; + if (i == ambiguousIndexCount.GetSize() - 1) { + e = BCExceptionChecksumInstance; + return NULL; + } + } + } + } + e = BCExceptionChecksumInstance; + return NULL; +} +CFX_PtrArray* CBC_PDF417ScanningDecoder::createBarcodeMatrix( + CBC_DetectionResult* detectionResult) { + CFX_PtrArray* barcodeMatrix = new CFX_PtrArray; + barcodeMatrix->SetSize(detectionResult->getBarcodeRowCount()); + CFX_PtrArray* temp = NULL; + int32_t colume = 0; + for (int32_t row = 0; row < barcodeMatrix->GetSize(); row++) { + temp = new CFX_PtrArray; + temp->SetSize(detectionResult->getBarcodeColumnCount() + 2); + for (colume = 0; colume < detectionResult->getBarcodeColumnCount() + 2; + colume++) { + temp->SetAt(colume, new CBC_BarcodeValue()); + } + barcodeMatrix->SetAt(row, temp); + } + colume = -1; + for (int32_t i = 0; + i < detectionResult->getDetectionResultColumns().GetSize(); i++) { + CBC_DetectionResultColumn* detectionResultColumn = + (CBC_DetectionResultColumn*)detectionResult->getDetectionResultColumns() + .GetAt(i); + colume++; + if (detectionResultColumn == NULL) { + continue; + } + CFX_PtrArray* temp = detectionResultColumn->getCodewords(); + for (int32_t l = 0; l < temp->GetSize(); l++) { + CBC_Codeword* codeword = (CBC_Codeword*)temp->GetAt(l); + if (codeword == NULL || codeword->getRowNumber() == -1) { + continue; + } + ((CBC_BarcodeValue*)((CFX_PtrArray*)barcodeMatrix->GetAt( + codeword->getRowNumber())) + ->GetAt(colume)) + ->setValue(codeword->getValue()); + } + } + return barcodeMatrix; +} +FX_BOOL CBC_PDF417ScanningDecoder::isValidBarcodeColumn( + CBC_DetectionResult* detectionResult, + int32_t barcodeColumn) { + return barcodeColumn >= 0 && + barcodeColumn <= detectionResult->getBarcodeColumnCount() + 1; +} +int32_t CBC_PDF417ScanningDecoder::getStartColumn( + CBC_DetectionResult* detectionResult, + int32_t barcodeColumn, + int32_t imageRow, + FX_BOOL leftToRight) { + int32_t offset = leftToRight ? 1 : -1; + CBC_Codeword* codeword = NULL; + if (isValidBarcodeColumn(detectionResult, barcodeColumn - offset)) { + codeword = detectionResult->getDetectionResultColumn(barcodeColumn - offset) + ->getCodeword(imageRow); + } + if (codeword) { + return leftToRight ? codeword->getEndX() : codeword->getStartX(); + } + codeword = detectionResult->getDetectionResultColumn(barcodeColumn) + ->getCodewordNearby(imageRow); + if (codeword) { + return leftToRight ? codeword->getStartX() : codeword->getEndX(); + } + if (isValidBarcodeColumn(detectionResult, barcodeColumn - offset)) { + codeword = detectionResult->getDetectionResultColumn(barcodeColumn - offset) + ->getCodewordNearby(imageRow); + } + if (codeword) { + return leftToRight ? codeword->getEndX() : codeword->getStartX(); + } + int32_t skippedColumns = 0; + while (isValidBarcodeColumn(detectionResult, barcodeColumn - offset)) { + barcodeColumn -= offset; + for (int32_t i = 0; + i < detectionResult->getDetectionResultColumn(barcodeColumn) + ->getCodewords() + ->GetSize(); + i++) { + CBC_Codeword* previousRowCodeword = + (CBC_Codeword*)detectionResult->getDetectionResultColumn( + barcodeColumn) + ->getCodewords() + ->GetAt(i); + if (previousRowCodeword) { + return (leftToRight ? previousRowCodeword->getEndX() + : previousRowCodeword->getStartX()) + + offset * skippedColumns * (previousRowCodeword->getEndX() - + previousRowCodeword->getStartX()); + } + } + skippedColumns++; + } + return leftToRight ? detectionResult->getBoundingBox()->getMinX() + : detectionResult->getBoundingBox()->getMaxX(); +} +CBC_Codeword* CBC_PDF417ScanningDecoder::detectCodeword( + CBC_CommonBitMatrix* image, + int32_t minColumn, + int32_t maxColumn, + FX_BOOL leftToRight, + int32_t startColumn, + int32_t imageRow, + int32_t minCodewordWidth, + int32_t maxCodewordWidth) { + startColumn = adjustCodewordStartColumn(image, minColumn, maxColumn, + leftToRight, startColumn, imageRow); + CFX_Int32Array* moduleBitCount = getModuleBitCount( + image, minColumn, maxColumn, leftToRight, startColumn, imageRow); + if (moduleBitCount == NULL) { + return NULL; + } + int32_t endColumn; + int32_t codewordBitCount = CBC_PDF417Common::getBitCountSum(*moduleBitCount); + if (leftToRight) { + endColumn = startColumn + codewordBitCount; + } else { + for (int32_t i = 0; i<moduleBitCount->GetSize()>> 1; i++) { + int32_t tmpCount = moduleBitCount->GetAt(i); + moduleBitCount->SetAt( + i, moduleBitCount->GetAt(moduleBitCount->GetSize() - 1 - i)); + moduleBitCount->SetAt(moduleBitCount->GetSize() - 1 - i, tmpCount); + } + endColumn = startColumn; + startColumn = endColumn - codewordBitCount; + } + int32_t decodedValue = + CBC_PDF417CodewordDecoder::getDecodedValue(*moduleBitCount); + int32_t codeword = CBC_PDF417Common::getCodeword(decodedValue); + delete moduleBitCount; + if (codeword == -1) { + return NULL; + } + return new CBC_Codeword(startColumn, endColumn, + getCodewordBucketNumber(decodedValue), codeword); +} +CFX_Int32Array* CBC_PDF417ScanningDecoder::getModuleBitCount( + CBC_CommonBitMatrix* image, + int32_t minColumn, + int32_t maxColumn, + FX_BOOL leftToRight, + int32_t startColumn, + int32_t imageRow) { + int32_t imageColumn = startColumn; + CFX_Int32Array* moduleBitCount = new CFX_Int32Array; + moduleBitCount->SetSize(8); + int32_t moduleNumber = 0; + int32_t increment = leftToRight ? 1 : -1; + FX_BOOL previousPixelValue = leftToRight; + while (((leftToRight && imageColumn < maxColumn) || + (!leftToRight && imageColumn >= minColumn)) && + moduleNumber < moduleBitCount->GetSize()) { + if (image->Get(imageColumn, imageRow) == previousPixelValue) { + moduleBitCount->SetAt(moduleNumber, + moduleBitCount->GetAt(moduleNumber) + 1); + imageColumn += increment; + } else { + moduleNumber++; + previousPixelValue = !previousPixelValue; + } + } + if (moduleNumber == moduleBitCount->GetSize() || + (((leftToRight && imageColumn == maxColumn) || + (!leftToRight && imageColumn == minColumn)) && + moduleNumber == moduleBitCount->GetSize() - 1)) { + return moduleBitCount; + } + delete moduleBitCount; + return NULL; +} +int32_t CBC_PDF417ScanningDecoder::getNumberOfECCodeWords( + int32_t barcodeECLevel) { + return 2 << barcodeECLevel; +} +int32_t CBC_PDF417ScanningDecoder::adjustCodewordStartColumn( + CBC_CommonBitMatrix* image, + int32_t minColumn, + int32_t maxColumn, + FX_BOOL leftToRight, + int32_t codewordStartColumn, + int32_t imageRow) { + int32_t correctedStartColumn = codewordStartColumn; + int32_t increment = leftToRight ? -1 : 1; + for (int32_t i = 0; i < 2; i++) { + while (((leftToRight && correctedStartColumn >= minColumn) || + (!leftToRight && correctedStartColumn < maxColumn)) && + leftToRight == image->Get(correctedStartColumn, imageRow)) { + if (abs(codewordStartColumn - correctedStartColumn) > + CODEWORD_SKEW_SIZE) { + return codewordStartColumn; + } + correctedStartColumn += increment; + } + increment = -increment; + leftToRight = !leftToRight; + } + return correctedStartColumn; +} +FX_BOOL CBC_PDF417ScanningDecoder::checkCodewordSkew(int32_t codewordSize, + int32_t minCodewordWidth, + int32_t maxCodewordWidth) { + return minCodewordWidth - CODEWORD_SKEW_SIZE <= codewordSize && + codewordSize <= maxCodewordWidth + CODEWORD_SKEW_SIZE; +} +CBC_CommonDecoderResult* CBC_PDF417ScanningDecoder::decodeCodewords( + CFX_Int32Array& codewords, + int32_t ecLevel, + CFX_Int32Array& erasures, + int32_t& e) { + if (codewords.GetSize() == 0) { + e = BCExceptionFormatInstance; + return NULL; + } + int32_t numECCodewords = 1 << (ecLevel + 1); + correctErrors(codewords, erasures, numECCodewords, e); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + verifyCodewordCount(codewords, numECCodewords, e); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + CFX_ByteString bytestring; + CBC_CommonDecoderResult* decoderResult = CBC_DecodedBitStreamPaser::decode( + codewords, bytestring.FormatInteger(ecLevel), e); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + return decoderResult; +} +int32_t CBC_PDF417ScanningDecoder::correctErrors(CFX_Int32Array& codewords, + CFX_Int32Array& erasures, + int32_t numECCodewords, + int32_t& e) { + if ((erasures.GetSize() != 0 && + erasures.GetSize() > (numECCodewords / 2 + MAX_ERRORS)) || + numECCodewords < 0 || numECCodewords > MAX_EC_CODEWORDS) { + e = BCExceptionChecksumInstance; + return -1; + } + int32_t result = CBC_PDF417ECErrorCorrection::decode( + codewords, numECCodewords, erasures, e); + BC_EXCEPTION_CHECK_ReturnValue(e, -1); + return result; +} +void CBC_PDF417ScanningDecoder::verifyCodewordCount(CFX_Int32Array& codewords, + int32_t numECCodewords, + int32_t& e) { + if (codewords.GetSize() < 4) { + e = BCExceptionFormatInstance; + return; + } + int32_t numberOfCodewords = codewords.GetAt(0); + if (numberOfCodewords > codewords.GetSize()) { + e = BCExceptionFormatInstance; + return; + } + if (numberOfCodewords == 0) { + if (numECCodewords < codewords.GetSize()) { + codewords[0] = codewords.GetSize() - numECCodewords; + } else { + e = BCExceptionFormatInstance; + return; + } + } +} +CFX_Int32Array* CBC_PDF417ScanningDecoder::getBitCountForCodeword( + int32_t codeword) { + CFX_Int32Array* result = new CFX_Int32Array; + result->SetSize(8); + int32_t previousValue = 0; + int32_t i = result->GetSize() - 1; + while (TRUE) { + if ((codeword & 0x1) != previousValue) { + previousValue = codeword & 0x1; + i--; + if (i < 0) { + break; + } + } + result->SetAt(i, result->GetAt(i) + 1); + codeword >>= 1; + } + return result; +} +int32_t CBC_PDF417ScanningDecoder::getCodewordBucketNumber(int32_t codeword) { + CFX_Int32Array* array = getBitCountForCodeword(codeword); + int32_t result = getCodewordBucketNumber(*array); + delete array; + return result; +} +int32_t CBC_PDF417ScanningDecoder::getCodewordBucketNumber( + CFX_Int32Array& moduleBitCount) { + return (moduleBitCount.GetAt(0) - moduleBitCount.GetAt(2) + + moduleBitCount.GetAt(4) - moduleBitCount.GetAt(6) + 9) % + 9; +} diff --git a/xfa/fxbarcode/pdf417/BC_PDF417ScanningDecoder.h b/xfa/fxbarcode/pdf417/BC_PDF417ScanningDecoder.h new file mode 100644 index 0000000000..6dbc125c31 --- /dev/null +++ b/xfa/fxbarcode/pdf417/BC_PDF417ScanningDecoder.h @@ -0,0 +1,119 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef XFA_FXBARCODE_PDF417_BC_PDF417SCANNINGDECODER_H_ +#define XFA_FXBARCODE_PDF417_BC_PDF417SCANNINGDECODER_H_ + +class CBC_CommonDecoderResult; +class CBC_CommonBitMatrix; +class CBC_Codeword; +class CBC_BoundingBox; +class CBC_ResultPoint; +class CBC_BarcodeMetadata; +class CBC_DetectionResult; +class CBC_DetectionResultRowIndicatorColumn; + +class CBC_PDF417ScanningDecoder { + public: + CBC_PDF417ScanningDecoder(); + virtual ~CBC_PDF417ScanningDecoder(); + static void Initialize(); + static void Finalize(); + static CBC_CommonDecoderResult* decode(CBC_CommonBitMatrix* image, + CBC_ResultPoint* imageTopLeft, + CBC_ResultPoint* imageBottomLeft, + CBC_ResultPoint* imageTopRight, + CBC_ResultPoint* imageBottomRight, + int32_t minCodewordWidth, + int32_t maxCodewordWidth, + int32_t& e); + static CFX_ByteString toString(CFX_PtrArray* barcodeMatrix); + + private: + static int32_t CODEWORD_SKEW_SIZE; + static int32_t MAX_ERRORS; + static int32_t MAX_EC_CODEWORDS; + static CBC_PDF417ECErrorCorrection* errorCorrection; + static CBC_DetectionResult* merge( + CBC_DetectionResultRowIndicatorColumn* leftRowIndicatorColumn, + CBC_DetectionResultRowIndicatorColumn* rightRowIndicatorColumn, + int32_t& e); + static CBC_BoundingBox* adjustBoundingBox( + CBC_DetectionResultRowIndicatorColumn* rowIndicatorColumn, + int32_t& e); + static int32_t getMax(CFX_Int32Array& values); + static CBC_BarcodeMetadata* getBarcodeMetadata( + CBC_DetectionResultRowIndicatorColumn* leftRowIndicatorColumn, + CBC_DetectionResultRowIndicatorColumn* rightRowIndicatorColumn); + static CBC_DetectionResultRowIndicatorColumn* getRowIndicatorColumn( + CBC_CommonBitMatrix* image, + CBC_BoundingBox* boundingBox, + CBC_ResultPoint startPoint, + FX_BOOL leftToRight, + int32_t minCodewordWidth, + int32_t maxCodewordWidth); + static void adjustCodewordCount(CBC_DetectionResult* detectionResult, + CFX_PtrArray* barcodeMatrix, + int32_t& e); + static CBC_CommonDecoderResult* createDecoderResult( + CBC_DetectionResult* detectionResult, + int32_t& e); + static CBC_CommonDecoderResult* createDecoderResultFromAmbiguousValues( + int32_t ecLevel, + CFX_Int32Array& codewords, + CFX_Int32Array& erasureArray, + CFX_Int32Array& ambiguousIndexes, + CFX_PtrArray& ambiguousIndexValues, + int32_t& e); + static CFX_PtrArray* createBarcodeMatrix( + CBC_DetectionResult* detectionResult); + static FX_BOOL isValidBarcodeColumn(CBC_DetectionResult* detectionResult, + int32_t barcodeColumn); + static int32_t getStartColumn(CBC_DetectionResult* detectionResult, + int32_t barcodeColumn, + int32_t imageRow, + FX_BOOL leftToRight); + static CBC_Codeword* detectCodeword(CBC_CommonBitMatrix* image, + int32_t minColumn, + int32_t maxColumn, + FX_BOOL leftToRight, + int32_t startColumn, + int32_t imageRow, + int32_t minCodewordWidth, + int32_t maxCodewordWidth); + static CFX_Int32Array* getModuleBitCount(CBC_CommonBitMatrix* image, + int32_t minColumn, + int32_t maxColumn, + FX_BOOL leftToRight, + int32_t startColumn, + int32_t imageRow); + static int32_t getNumberOfECCodeWords(int32_t barcodeECLevel); + static int32_t adjustCodewordStartColumn(CBC_CommonBitMatrix* image, + int32_t minColumn, + int32_t maxColumn, + FX_BOOL leftToRight, + int32_t codewordStartColumn, + int32_t imageRow); + static FX_BOOL checkCodewordSkew(int32_t codewordSize, + int32_t minCodewordWidth, + int32_t maxCodewordWidth); + static CBC_CommonDecoderResult* decodeCodewords(CFX_Int32Array& codewords, + int32_t ecLevel, + CFX_Int32Array& erasures, + int32_t& e); + static int32_t correctErrors(CFX_Int32Array& codewords, + CFX_Int32Array& erasures, + int32_t numECCodewords, + int32_t& e); + static void verifyCodewordCount(CFX_Int32Array& codewords, + int32_t numECCodewords, + int32_t& e); + static CFX_Int32Array* getBitCountForCodeword(int32_t codeword); + static int32_t getCodewordBucketNumber(int32_t codeword); + static int32_t getCodewordBucketNumber(CFX_Int32Array& moduleBitCount); +}; + +#endif // XFA_FXBARCODE_PDF417_BC_PDF417SCANNINGDECODER_H_ diff --git a/xfa/fxbarcode/pdf417/BC_PDF417Writer.cpp b/xfa/fxbarcode/pdf417/BC_PDF417Writer.cpp new file mode 100644 index 0000000000..765c1d613c --- /dev/null +++ b/xfa/fxbarcode/pdf417/BC_PDF417Writer.cpp @@ -0,0 +1,115 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com +// Original code is licensed as follows: +/* + * Copyright 2012 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "xfa/fxbarcode/BC_TwoDimWriter.h" +#include "xfa/fxbarcode/common/BC_CommonBitArray.h" +#include "xfa/fxbarcode/common/BC_CommonBitMatrix.h" +#include "xfa/fxbarcode/pdf417/BC_PDF417.h" +#include "xfa/fxbarcode/pdf417/BC_PDF417BarcodeMatrix.h" +#include "xfa/fxbarcode/pdf417/BC_PDF417Compaction.h" +#include "xfa/fxbarcode/pdf417/BC_PDF417Writer.h" + +CBC_PDF417Writer::CBC_PDF417Writer() { + m_bFixedSize = FALSE; +} +CBC_PDF417Writer::~CBC_PDF417Writer() { + m_bTruncated = TRUE; +} +FX_BOOL CBC_PDF417Writer::SetErrorCorrectionLevel(int32_t level) { + if (level < 0 || level > 8) { + return FALSE; + } + m_iCorrectLevel = level; + return TRUE; +} +void CBC_PDF417Writer::SetTruncated(FX_BOOL truncated) { + m_bTruncated = truncated; +} +uint8_t* CBC_PDF417Writer::Encode(const CFX_WideString& contents, + int32_t& outWidth, + int32_t& outHeight, + int32_t& e) { + CBC_PDF417 encoder; + int32_t col = (m_Width / m_ModuleWidth - 69) / 17; + int32_t row = m_Height / (m_ModuleWidth * 20); + if (row >= 3 && row <= 90 && col >= 1 && col <= 30) { + encoder.setDimensions(col, col, row, row); + } else if (col >= 1 && col <= 30) { + encoder.setDimensions(col, col, 90, 3); + } else if (row >= 3 && row <= 90) { + encoder.setDimensions(30, 1, row, row); + } + encoder.generateBarcodeLogic(contents, m_iCorrectLevel, e); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + int32_t lineThickness = 2; + int32_t aspectRatio = 4; + CBC_BarcodeMatrix* barcodeMatrix = encoder.getBarcodeMatrix(); + CFX_ByteArray originalScale; + originalScale.Copy(barcodeMatrix->getScaledMatrix( + lineThickness, aspectRatio * lineThickness)); + int32_t width = outWidth; + int32_t height = outHeight; + outWidth = barcodeMatrix->getWidth(); + outHeight = barcodeMatrix->getHeight(); + FX_BOOL rotated = FALSE; + if ((height > width) ^ (outWidth < outHeight)) { + rotateArray(originalScale, outHeight, outWidth); + rotated = TRUE; + int32_t temp = outHeight; + outHeight = outWidth; + outWidth = temp; + } + int32_t scaleX = width / outWidth; + int32_t scaleY = height / outHeight; + int32_t scale; + if (scaleX < scaleY) { + scale = scaleX; + } else { + scale = scaleY; + } + if (scale > 1) { + originalScale.RemoveAll(); + originalScale.Copy(barcodeMatrix->getScaledMatrix( + scale * lineThickness, scale * aspectRatio * lineThickness)); + if (rotated) { + rotateArray(originalScale, outHeight, outWidth); + int32_t temp = outHeight; + outHeight = outWidth; + outWidth = temp; + } + } + uint8_t* result = FX_Alloc2D(uint8_t, outHeight, outWidth); + FXSYS_memcpy(result, originalScale.GetData(), outHeight * outWidth); + return result; +} +void CBC_PDF417Writer::rotateArray(CFX_ByteArray& bitarray, + int32_t height, + int32_t width) { + CFX_ByteArray temp; + temp.Copy(bitarray); + for (int32_t ii = 0; ii < height; ii++) { + int32_t inverseii = height - ii - 1; + for (int32_t jj = 0; jj < width; jj++) { + bitarray[jj * height + inverseii] = temp[ii * width + jj]; + } + } +} diff --git a/xfa/fxbarcode/pdf417/BC_PDF417Writer.h b/xfa/fxbarcode/pdf417/BC_PDF417Writer.h new file mode 100644 index 0000000000..f92f57b82c --- /dev/null +++ b/xfa/fxbarcode/pdf417/BC_PDF417Writer.h @@ -0,0 +1,28 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef XFA_FXBARCODE_PDF417_BC_PDF417WRITER_H_ +#define XFA_FXBARCODE_PDF417_BC_PDF417WRITER_H_ + +class CBC_TwoDimWriter; +class CBC_PDF417Writer; +class CBC_PDF417Writer : public CBC_TwoDimWriter { + public: + CBC_PDF417Writer(); + virtual ~CBC_PDF417Writer(); + uint8_t* Encode(const CFX_WideString& contents, + int32_t& outWidth, + int32_t& outHeight, + int32_t& e); + FX_BOOL SetErrorCorrectionLevel(int32_t level); + void SetTruncated(FX_BOOL truncated); + + private: + void rotateArray(CFX_ByteArray& bitarray, int32_t width, int32_t height); + FX_BOOL m_bTruncated; +}; + +#endif // XFA_FXBARCODE_PDF417_BC_PDF417WRITER_H_ diff --git a/xfa/fxbarcode/qrcode/BC_FinderPatternInfo.cpp b/xfa/fxbarcode/qrcode/BC_FinderPatternInfo.cpp new file mode 100644 index 0000000000..25dc28b3f3 --- /dev/null +++ b/xfa/fxbarcode/qrcode/BC_FinderPatternInfo.cpp @@ -0,0 +1,41 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com +// Original code is licensed as follows: +/* + * Copyright 2007 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "xfa/fxbarcode/BC_ResultPoint.h" +#include "xfa/fxbarcode/qrcode/BC_FinderPatternInfo.h" +#include "xfa/fxbarcode/qrcode/BC_QRFinderPattern.h" + +CBC_QRFinderPatternInfo::CBC_QRFinderPatternInfo(CFX_PtrArray* patternCenters) { + m_bottomLeft = (CBC_QRFinderPattern*)(*patternCenters)[0]; + m_topLeft = (CBC_QRFinderPattern*)(*patternCenters)[1]; + m_topRight = (CBC_QRFinderPattern*)(*patternCenters)[2]; +} +CBC_QRFinderPatternInfo::~CBC_QRFinderPatternInfo() {} +CBC_QRFinderPattern* CBC_QRFinderPatternInfo::GetBottomLeft() { + return m_bottomLeft; +} +CBC_QRFinderPattern* CBC_QRFinderPatternInfo::GetTopLeft() { + return m_topLeft; +} +CBC_QRFinderPattern* CBC_QRFinderPatternInfo::GetTopRight() { + return m_topRight; +} diff --git a/xfa/fxbarcode/qrcode/BC_FinderPatternInfo.h b/xfa/fxbarcode/qrcode/BC_FinderPatternInfo.h new file mode 100644 index 0000000000..0acb106856 --- /dev/null +++ b/xfa/fxbarcode/qrcode/BC_FinderPatternInfo.h @@ -0,0 +1,28 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef XFA_FXBARCODE_QRCODE_BC_FINDERPATTERNINFO_H_ +#define XFA_FXBARCODE_QRCODE_BC_FINDERPATTERNINFO_H_ + +#include "core/include/fxcrt/fx_basic.h" + +class CBC_QRFinderPattern; + +class CBC_QRFinderPatternInfo { + private: + CBC_QRFinderPattern* m_bottomLeft; + CBC_QRFinderPattern* m_topLeft; + CBC_QRFinderPattern* m_topRight; + + public: + CBC_QRFinderPatternInfo(CFX_PtrArray* patternCenters); + virtual ~CBC_QRFinderPatternInfo(); + CBC_QRFinderPattern* GetBottomLeft(); + CBC_QRFinderPattern* GetTopLeft(); + CBC_QRFinderPattern* GetTopRight(); +}; + +#endif // XFA_FXBARCODE_QRCODE_BC_FINDERPATTERNINFO_H_ diff --git a/xfa/fxbarcode/qrcode/BC_QRAlignmentPattern.cpp b/xfa/fxbarcode/qrcode/BC_QRAlignmentPattern.cpp new file mode 100644 index 0000000000..4d5a36e250 --- /dev/null +++ b/xfa/fxbarcode/qrcode/BC_QRAlignmentPattern.cpp @@ -0,0 +1,49 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com +// Original code is licensed as follows: +/* + * Copyright 2007 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "xfa/fxbarcode/BC_ResultPoint.h" +#include "xfa/fxbarcode/qrcode/BC_QRAlignmentPattern.h" + +CBC_QRAlignmentPattern::CBC_QRAlignmentPattern(FX_FLOAT posX, + FX_FLOAT posY, + FX_FLOAT estimateModuleSize) + : CBC_ResultPoint(posX, posY), m_moduleSize(estimateModuleSize) {} +CBC_QRAlignmentPattern::~CBC_QRAlignmentPattern() {} +FX_FLOAT CBC_QRAlignmentPattern::GetX() { + return m_x; +} +FX_FLOAT CBC_QRAlignmentPattern::GetY() { + return m_y; +} +FX_BOOL CBC_QRAlignmentPattern::AboutEquals(FX_FLOAT moduleSize, + FX_FLOAT i, + FX_FLOAT j) { + if ((FXSYS_fabs(i - GetY()) <= moduleSize) && + (FXSYS_fabs(j - GetX()) <= moduleSize)) { + FX_FLOAT moduleSizeDiff = FXSYS_fabs(moduleSize - m_moduleSize); + return (moduleSizeDiff <= 1.0f) || (moduleSizeDiff / m_moduleSize <= 1.0f); + } + return FALSE; +} +CBC_QRAlignmentPattern* CBC_QRAlignmentPattern::Clone() { + return new CBC_QRAlignmentPattern(m_x, m_y, m_moduleSize); +} diff --git a/xfa/fxbarcode/qrcode/BC_QRAlignmentPattern.h b/xfa/fxbarcode/qrcode/BC_QRAlignmentPattern.h new file mode 100644 index 0000000000..9a4e80c2b2 --- /dev/null +++ b/xfa/fxbarcode/qrcode/BC_QRAlignmentPattern.h @@ -0,0 +1,25 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef XFA_FXBARCODE_QRCODE_BC_QRALIGNMENTPATTERN_H_ +#define XFA_FXBARCODE_QRCODE_BC_QRALIGNMENTPATTERN_H_ +class CBC_ResultPoint; +class CBC_QRAlignmentPattern : public CBC_ResultPoint { + private: + FX_FLOAT m_moduleSize; + + public: + CBC_QRAlignmentPattern(FX_FLOAT posX, + FX_FLOAT posY, + FX_FLOAT estimateModuleSize); + virtual ~CBC_QRAlignmentPattern(); + FX_BOOL AboutEquals(FX_FLOAT moduleSize, FX_FLOAT i, FX_FLOAT j); + FX_FLOAT GetX(); + FX_FLOAT GetY(); + CBC_QRAlignmentPattern* Clone(); +}; + +#endif // XFA_FXBARCODE_QRCODE_BC_QRALIGNMENTPATTERN_H_ diff --git a/xfa/fxbarcode/qrcode/BC_QRAlignmentPatternFinder.cpp b/xfa/fxbarcode/qrcode/BC_QRAlignmentPatternFinder.cpp new file mode 100644 index 0000000000..8c462bf328 --- /dev/null +++ b/xfa/fxbarcode/qrcode/BC_QRAlignmentPatternFinder.cpp @@ -0,0 +1,200 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com +// Original code is licensed as follows: +/* + * Copyright 2007 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "xfa/fxbarcode/BC_ResultPoint.h" +#include "xfa/fxbarcode/common/BC_CommonBitMatrix.h" +#include "xfa/fxbarcode/qrcode/BC_QRAlignmentPattern.h" +#include "xfa/fxbarcode/qrcode/BC_QRAlignmentPatternFinder.h" + +CBC_QRAlignmentPatternFinder::CBC_QRAlignmentPatternFinder( + CBC_CommonBitMatrix* image, + int32_t startX, + int32_t startY, + int32_t width, + int32_t height, + FX_FLOAT moduleSize) + : m_image(image), + m_startX(startX), + m_startY(startY), + m_width(width), + m_height(height), + m_moduleSize(moduleSize) { + m_crossCheckStateCount.SetSize(3); +} +CBC_QRAlignmentPatternFinder::~CBC_QRAlignmentPatternFinder() { + for (int32_t i = 0; i < m_possibleCenters.GetSize(); i++) { + delete (CBC_QRAlignmentPattern*)m_possibleCenters[i]; + } + m_possibleCenters.RemoveAll(); +} +CBC_QRAlignmentPattern* CBC_QRAlignmentPatternFinder::Find(int32_t& e) { + int32_t startX = m_startX; + int32_t height = m_height; + int32_t maxJ = startX + m_width; + int32_t middleI = m_startY + (height >> 1); + CFX_Int32Array stateCount; + stateCount.SetSize(3); + for (int32_t iGen = 0; iGen < height; iGen++) { + int32_t i = + middleI + ((iGen & 0x01) == 0 ? ((iGen + 1) >> 1) : -((iGen + 1) >> 1)); + stateCount[0] = 0; + stateCount[1] = 0; + stateCount[2] = 0; + int32_t j = startX; + while (j < maxJ && !m_image->Get(j, i)) { + j++; + } + int32_t currentState = 0; + while (j < maxJ) { + if (m_image->Get(j, i)) { + if (currentState == 1) { + stateCount[currentState]++; + } else { + if (currentState == 2) { + if (FoundPatternCross(stateCount)) { + CBC_QRAlignmentPattern* confirmed = + HandlePossibleCenter(stateCount, i, j); + if (confirmed) { + return confirmed; + } + } + stateCount[0] = stateCount[2]; + stateCount[1] = 1; + stateCount[2] = 0; + currentState = 1; + } else { + stateCount[++currentState]++; + } + } + } else { + if (currentState == 1) { + currentState++; + } + stateCount[currentState]++; + } + j++; + } + if (FoundPatternCross(stateCount)) { + CBC_QRAlignmentPattern* confirmed = + HandlePossibleCenter(stateCount, i, maxJ); + if (confirmed) { + return confirmed; + } + } + } + if (m_possibleCenters.GetSize() != 0) { + return ((CBC_QRAlignmentPattern*)(m_possibleCenters[0]))->Clone(); + } + e = BCExceptionRead; + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + return NULL; +} +FX_FLOAT CBC_QRAlignmentPatternFinder::CenterFromEnd( + const CFX_Int32Array& stateCount, + int32_t end) { + return (FX_FLOAT)(end - stateCount[2]) - stateCount[1] / 2.0f; +} +FX_BOOL CBC_QRAlignmentPatternFinder::FoundPatternCross( + const CFX_Int32Array& stateCount) { + FX_FLOAT moduleSize = m_moduleSize; + FX_FLOAT maxVariance = moduleSize / 2.0f; + for (int32_t i = 0; i < 3; i++) { + if (fabs(moduleSize - stateCount[i]) >= maxVariance) { + return false; + } + } + return TRUE; +} +FX_FLOAT CBC_QRAlignmentPatternFinder::CrossCheckVertical( + int32_t startI, + int32_t centerJ, + int32_t maxCount, + int32_t originalStateCountTotal) { + int32_t maxI = m_image->GetHeight(); + CFX_Int32Array stateCount; + stateCount.Copy(m_crossCheckStateCount); + stateCount[0] = 0; + stateCount[1] = 0; + stateCount[2] = 0; + int32_t i = startI; + while (i >= 0 && m_image->Get(centerJ, i) && stateCount[1] <= maxCount) { + stateCount[1]++; + i--; + } + if (i < 0 || stateCount[1] > maxCount) { + return FXSYS_nan(); + } + while (i >= 0 && !m_image->Get(centerJ, i) && stateCount[0] <= maxCount) { + stateCount[0]++; + i--; + } + if (stateCount[0] > maxCount) { + return FXSYS_nan(); + } + i = startI + 1; + while (i < maxI && m_image->Get(centerJ, i) && stateCount[1] <= maxCount) { + stateCount[1]++; + i++; + } + if (i == maxI || stateCount[1] > maxCount) { + return FXSYS_nan(); + } + while (i < maxI && !m_image->Get(centerJ, i) && stateCount[2] <= maxCount) { + stateCount[2]++; + i++; + } + if (stateCount[2] > maxCount) { + return FXSYS_nan(); + } + int32_t stateCountTotal = stateCount[0] + stateCount[1] + stateCount[2]; + if (5 * abs(stateCountTotal - originalStateCountTotal) >= + originalStateCountTotal) { + return FXSYS_nan(); + } + return FoundPatternCross(stateCount) ? CenterFromEnd(stateCount, i) + : FXSYS_nan(); +} +CBC_QRAlignmentPattern* CBC_QRAlignmentPatternFinder::HandlePossibleCenter( + const CFX_Int32Array& stateCount, + int32_t i, + int32_t j) { + int32_t stateCountTotal = stateCount[0] + stateCount[1] + stateCount[2]; + FX_FLOAT centerJ = CenterFromEnd(stateCount, j); + FX_FLOAT centerI = CrossCheckVertical(i, (int32_t)centerJ, 2 * stateCount[1], + stateCountTotal); + if (!FXSYS_isnan(centerI)) { + FX_FLOAT estimatedModuleSize = + (FX_FLOAT)(stateCount[0] + stateCount[1] + stateCount[2]) / 3.0f; + int32_t max = m_possibleCenters.GetSize(); + for (int32_t index = 0; index < max; index++) { + CBC_QRAlignmentPattern* center = + (CBC_QRAlignmentPattern*)(m_possibleCenters[index]); + if (center->AboutEquals(estimatedModuleSize, centerI, centerJ)) { + return new CBC_QRAlignmentPattern(centerJ, centerI, + estimatedModuleSize); + } + } + m_possibleCenters.Add( + new CBC_QRAlignmentPattern(centerJ, centerI, estimatedModuleSize)); + } + return NULL; +} diff --git a/xfa/fxbarcode/qrcode/BC_QRAlignmentPatternFinder.h b/xfa/fxbarcode/qrcode/BC_QRAlignmentPatternFinder.h new file mode 100644 index 0000000000..0b1a2a7ca7 --- /dev/null +++ b/xfa/fxbarcode/qrcode/BC_QRAlignmentPatternFinder.h @@ -0,0 +1,47 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef XFA_FXBARCODE_QRCODE_BC_QRALIGNMENTPATTERNFINDER_H_ +#define XFA_FXBARCODE_QRCODE_BC_QRALIGNMENTPATTERNFINDER_H_ + +#include "core/include/fxcrt/fx_basic.h" +#include "xfa/fxbarcode/utils.h" + +class CBC_CommonBitMatrix; +class CBC_QRAlignmentPattern; + +class CBC_QRAlignmentPatternFinder { + private: + CBC_CommonBitMatrix* m_image; + CFX_PtrArray m_possibleCenters; + int32_t m_startX; + int32_t m_startY; + int32_t m_width; + int32_t m_height; + FX_FLOAT m_moduleSize; + CFX_Int32Array m_crossCheckStateCount; + + public: + CBC_QRAlignmentPatternFinder(CBC_CommonBitMatrix* image, + int32_t startX, + int32_t startY, + int32_t width, + int32_t height, + FX_FLOAT moduleSize); + virtual ~CBC_QRAlignmentPatternFinder(); + FX_BOOL FoundPatternCross(const CFX_Int32Array& stateCount); + FX_FLOAT CrossCheckVertical(int32_t startI, + int32_t startJ, + int32_t maxCount, + int32_t originalStateCountTotal); + CBC_QRAlignmentPattern* Find(int32_t& e); + CBC_QRAlignmentPattern* HandlePossibleCenter(const CFX_Int32Array& stateCount, + int32_t i, + int32_t j); + static FX_FLOAT CenterFromEnd(const CFX_Int32Array& stateCount, int32_t end); +}; + +#endif // XFA_FXBARCODE_QRCODE_BC_QRALIGNMENTPATTERNFINDER_H_ diff --git a/xfa/fxbarcode/qrcode/BC_QRBitMatrixParser.cpp b/xfa/fxbarcode/qrcode/BC_QRBitMatrixParser.cpp new file mode 100644 index 0000000000..53803588b5 --- /dev/null +++ b/xfa/fxbarcode/qrcode/BC_QRBitMatrixParser.cpp @@ -0,0 +1,183 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com +// Original code is licensed as follows: +/* + * Copyright 2007 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "xfa/fxbarcode/qrcode/BC_QRBitMatrixParser.h" + +#include <memory> + +#include "xfa/fxbarcode/common/BC_CommonBitMatrix.h" +#include "xfa/fxbarcode/qrcode/BC_QRCoderFormatInformation.h" +#include "xfa/fxbarcode/qrcode/BC_QRCoderVersion.h" +#include "xfa/fxbarcode/qrcode/BC_QRDataMask.h" +#include "xfa/fxbarcode/utils.h" + +CBC_QRBitMatrixParser::CBC_QRBitMatrixParser() {} +void CBC_QRBitMatrixParser::Init(CBC_CommonBitMatrix* bitMatrix, int32_t& e) { + m_dimension = bitMatrix->GetDimension(e); + BC_EXCEPTION_CHECK_ReturnVoid(e); + m_tempBitMatrix = bitMatrix; + if (m_dimension < 21 || (m_dimension & 0x03) != 1) { + e = BCExceptionRead; + BC_EXCEPTION_CHECK_ReturnVoid(e); + } + m_bitMatrix = m_tempBitMatrix; + m_parsedFormatInfo = NULL; + m_version = NULL; +} +CBC_QRBitMatrixParser::~CBC_QRBitMatrixParser() { + delete m_parsedFormatInfo; +} +CBC_QRCoderFormatInformation* CBC_QRBitMatrixParser::ReadFormatInformation( + int32_t& e) { + if (m_parsedFormatInfo) { + return m_parsedFormatInfo; + } + int32_t formatInfoBits = 0; + int32_t j; + for (j = 0; j < 6; j++) { + formatInfoBits = CopyBit(8, j, formatInfoBits); + } + formatInfoBits = CopyBit(8, 7, formatInfoBits); + formatInfoBits = CopyBit(8, 8, formatInfoBits); + formatInfoBits = CopyBit(7, 8, formatInfoBits); + for (int32_t i = 5; i >= 0; i--) { + formatInfoBits = CopyBit(i, 8, formatInfoBits); + } + m_parsedFormatInfo = + CBC_QRCoderFormatInformation::DecodeFormatInformation(formatInfoBits); + if (m_parsedFormatInfo) { + return m_parsedFormatInfo; + } + int32_t dimension = m_bitMatrix->GetDimension(e); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + formatInfoBits = 0; + int32_t iMin = dimension - 8; + for (j = dimension - 1; j >= iMin; j--) { + formatInfoBits = CopyBit(j, 8, formatInfoBits); + } + for (int32_t k = dimension - 7; k < dimension; k++) { + formatInfoBits = CopyBit(8, k, formatInfoBits); + } + m_parsedFormatInfo = + CBC_QRCoderFormatInformation::DecodeFormatInformation(formatInfoBits); + if (m_parsedFormatInfo) { + return m_parsedFormatInfo; + } + e = BCExceptionRead; + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + return NULL; +} +CBC_QRCoderVersion* CBC_QRBitMatrixParser::ReadVersion(int32_t& e) { + if (m_version) { + return m_version; + } + int32_t dimension = m_bitMatrix->GetDimension(e); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + int32_t provisionVersion = (dimension - 17) >> 2; + if (provisionVersion <= 6) { + CBC_QRCoderVersion* qrv = + CBC_QRCoderVersion::GetVersionForNumber(provisionVersion, e); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + return qrv; + } + int32_t versionBits = 0; + for (int32_t i = 5; i >= 0; i--) { + int32_t jMin = dimension - 11; + for (int32_t j = dimension - 9; j >= jMin; j--) { + versionBits = CopyBit(i, j, versionBits); + } + } + m_version = CBC_QRCoderVersion::DecodeVersionInformation(versionBits, e); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + if (m_version && m_version->GetDimensionForVersion() == dimension) { + return m_version; + } + versionBits = 0; + for (int32_t j = 5; j >= 0; j--) { + int32_t iMin = dimension - 11; + for (int32_t i = dimension - 9; i >= iMin; i--) { + versionBits = CopyBit(i, j, versionBits); + } + } + m_version = CBC_QRCoderVersion::DecodeVersionInformation(versionBits, e); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + if (m_version && m_version->GetDimensionForVersion() == dimension) { + return m_version; + } + e = BCExceptionRead; + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + return NULL; +} +int32_t CBC_QRBitMatrixParser::CopyBit(int32_t i, + int32_t j, + int32_t versionBits) { + return m_bitMatrix->Get(j, i) ? (versionBits << 1) | 0x1 : versionBits << 1; +} +CFX_ByteArray* CBC_QRBitMatrixParser::ReadCodewords(int32_t& e) { + CBC_QRCoderFormatInformation* formatInfo = ReadFormatInformation(e); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL) CBC_QRCoderVersion* version = + ReadVersion(e); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + CBC_QRDataMask* dataMask = + CBC_QRDataMask::ForReference((int32_t)(formatInfo->GetDataMask()), e); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + int32_t dimension = m_bitMatrix->GetDimension(e); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + dataMask->UnmaskBitMatirx(m_bitMatrix, dimension); + std::unique_ptr<CBC_CommonBitMatrix> functionPattern( + version->BuildFunctionPattern(e)); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + FX_BOOL readingUp = TRUE; + std::unique_ptr<CFX_ByteArray> result(new CFX_ByteArray); + result->SetSize(version->GetTotalCodeWords()); + int32_t resultOffset = 0; + int32_t currentByte = 0; + int32_t bitsRead = 0; + for (int32_t j = dimension - 1; j > 0; j -= 2) { + if (j == 6) { + j--; + } + for (int32_t count = 0; count < dimension; count++) { + int32_t i = readingUp ? dimension - 1 - count : count; + for (int32_t col = 0; col < 2; col++) { + if (!functionPattern->Get(j - col, i)) { + bitsRead++; + currentByte <<= 1; + if (m_bitMatrix->Get(j - col, i)) { + currentByte |= 1; + } + if (bitsRead == 8) { + (*result)[resultOffset++] = (uint8_t)currentByte; + bitsRead = 0; + currentByte = 0; + } + } + } + } + readingUp ^= TRUE; + } + if (resultOffset != version->GetTotalCodeWords()) { + e = BCExceptionRead; + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + } + return result.release(); +} diff --git a/xfa/fxbarcode/qrcode/BC_QRBitMatrixParser.h b/xfa/fxbarcode/qrcode/BC_QRBitMatrixParser.h new file mode 100644 index 0000000000..6bb1064cd2 --- /dev/null +++ b/xfa/fxbarcode/qrcode/BC_QRBitMatrixParser.h @@ -0,0 +1,34 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef XFA_FXBARCODE_QRCODE_BC_QRBITMATRIXPARSER_H_ +#define XFA_FXBARCODE_QRCODE_BC_QRBITMATRIXPARSER_H_ + +#include "core/include/fxcrt/fx_basic.h" + +class CBC_CommonBitMatrix; +class CBC_QRCoderVersion; +class CBC_QRCoderFormatInformation; + +class CBC_QRBitMatrixParser { + private: + CBC_CommonBitMatrix* m_bitMatrix; + CBC_CommonBitMatrix* m_tempBitMatrix; + CBC_QRCoderVersion* m_version; + CBC_QRCoderFormatInformation* m_parsedFormatInfo; + int32_t m_dimension; + + public: + CBC_QRBitMatrixParser(); + virtual ~CBC_QRBitMatrixParser(); + CBC_QRCoderFormatInformation* ReadFormatInformation(int32_t& e); + CBC_QRCoderVersion* ReadVersion(int32_t& e); + int32_t CopyBit(int32_t i, int32_t j, int32_t versionBits); + CFX_ByteArray* ReadCodewords(int32_t& e); + virtual void Init(CBC_CommonBitMatrix* bitMatrix, int32_t& e); +}; + +#endif // XFA_FXBARCODE_QRCODE_BC_QRBITMATRIXPARSER_H_ diff --git a/xfa/fxbarcode/qrcode/BC_QRCodeReader.cpp b/xfa/fxbarcode/qrcode/BC_QRCodeReader.cpp new file mode 100644 index 0000000000..716b6c17de --- /dev/null +++ b/xfa/fxbarcode/qrcode/BC_QRCodeReader.cpp @@ -0,0 +1,108 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com +// Original code is licensed as follows: +/* + * Copyright 2007 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "xfa/fxbarcode/qrcode/BC_QRCodeReader.h" + +#include <memory> + +#include "xfa/fxbarcode/BC_Binarizer.h" +#include "xfa/fxbarcode/BC_BinaryBitmap.h" +#include "xfa/fxbarcode/BC_BufferedImageLuminanceSource.h" +#include "xfa/fxbarcode/BC_LuminanceSource.h" +#include "xfa/fxbarcode/BC_Reader.h" +#include "xfa/fxbarcode/BC_ResultPoint.h" +#include "xfa/fxbarcode/common/BC_CommonDecoderResult.h" +#include "xfa/fxbarcode/common/BC_GlobalHistogramBinarizer.h" +#include "xfa/fxbarcode/common/reedsolomon/BC_ReedSolomonGF256.h" +#include "xfa/fxbarcode/qrcode/BC_QRCoderDecoder.h" +#include "xfa/fxbarcode/qrcode/BC_QRCoderErrorCorrectionLevel.h" +#include "xfa/fxbarcode/qrcode/BC_QRCoderMode.h" +#include "xfa/fxbarcode/qrcode/BC_QRCoderVersion.h" +#include "xfa/fxbarcode/qrcode/BC_QRDataMask.h" +#include "xfa/fxbarcode/qrcode/BC_QRDetector.h" +#include "xfa/fxbarcode/qrcode/BC_QRDetectorResult.h" + +CBC_QRCodeReader::CBC_QRCodeReader() : m_decoder(NULL) {} +void CBC_QRCodeReader::Init() { + m_decoder = new CBC_QRCoderDecoder; + m_decoder->Init(); +} +CBC_QRCodeReader::~CBC_QRCodeReader() { + delete m_decoder; +} +CFX_ByteString CBC_QRCodeReader::Decode(CBC_BinaryBitmap* image, + int32_t hints, + int32_t& e) { + CBC_CommonBitMatrix* matrix = image->GetMatrix(e); + BC_EXCEPTION_CHECK_ReturnValue(e, ""); + CBC_QRDetector detector(matrix); + std::unique_ptr<CBC_QRDetectorResult> detectorResult( + detector.Detect(hints, e)); + BC_EXCEPTION_CHECK_ReturnValue(e, ""); + std::unique_ptr<CBC_CommonDecoderResult> decodeResult( + m_decoder->Decode(detectorResult->GetBits(), 0, e)); + BC_EXCEPTION_CHECK_ReturnValue(e, ""); + return (decodeResult->GetText()); +} +CFX_ByteString CBC_QRCodeReader::Decode(const CFX_WideString& filename, + int32_t hints, + int32_t byteModeDecode, + int32_t& e) { + CBC_BufferedImageLuminanceSource source(filename); + source.Init(e); + BC_EXCEPTION_CHECK_ReturnValue(e, ""); + CBC_GlobalHistogramBinarizer binarizer(&source); + CBC_BinaryBitmap bitmap(&binarizer); + CFX_ByteString bs = Decode(&bitmap, hints, e); + BC_EXCEPTION_CHECK_ReturnValue(e, ""); + return bs; +} +CFX_ByteString CBC_QRCodeReader::Decode(CFX_DIBitmap* pBitmap, + int32_t hints, + int32_t byteModeDecode, + int32_t& e) { + CBC_BufferedImageLuminanceSource source(pBitmap); + CBC_GlobalHistogramBinarizer binarizer(&source); + CBC_BinaryBitmap bitmap(&binarizer); + CFX_ByteString bs = Decode(&bitmap, hints, e); + BC_EXCEPTION_CHECK_ReturnValue(e, ""); + return bs; +} +CFX_ByteString CBC_QRCodeReader::Decode(CBC_BinaryBitmap* image, int32_t& e) { + CFX_ByteString bs = Decode(image, 0, e); + BC_EXCEPTION_CHECK_ReturnValue(e, ""); + return bs; +} +void CBC_QRCodeReader::ReleaseAll() { + if (CBC_ReedSolomonGF256::QRCodeFild) { + delete CBC_ReedSolomonGF256::QRCodeFild; + CBC_ReedSolomonGF256::QRCodeFild = NULL; + } + if (CBC_ReedSolomonGF256::DataMatrixField) { + delete CBC_ReedSolomonGF256::DataMatrixField; + CBC_ReedSolomonGF256::DataMatrixField = NULL; + } + CBC_QRCoderMode::Destroy(); + CBC_QRCoderErrorCorrectionLevel::Destroy(); + CBC_QRDataMask::Destroy(); + CBC_QRCoderVersion::Destroy(); +} diff --git a/xfa/fxbarcode/qrcode/BC_QRCodeReader.h b/xfa/fxbarcode/qrcode/BC_QRCodeReader.h new file mode 100644 index 0000000000..72dd453953 --- /dev/null +++ b/xfa/fxbarcode/qrcode/BC_QRCodeReader.h @@ -0,0 +1,40 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef XFA_FXBARCODE_QRCODE_BC_QRCODEREADER_H_ +#define XFA_FXBARCODE_QRCODE_BC_QRCODEREADER_H_ + +#include <stdint.h> + +#include "core/include/fxcrt/fx_string.h" +#include "xfa/fxbarcode/BC_Reader.h" + +class CBC_BinaryBitmap; +class CBC_QRCoderDecoder; +class CFX_DIBitmap; + +class CBC_QRCodeReader : public CBC_Reader { + private: + CBC_QRCoderDecoder* m_decoder; + + public: + CBC_QRCodeReader(); + virtual ~CBC_QRCodeReader(); + CFX_ByteString Decode(CFX_DIBitmap* pBitmap, + int32_t hints, + int32_t byteModeDecode, + int32_t& e); + CFX_ByteString Decode(const CFX_WideString& filename, + int32_t hints, + int32_t byteModeDecode, + int32_t& e); + static void ReleaseAll(); + CFX_ByteString Decode(CBC_BinaryBitmap* image, int32_t hints, int32_t& e); + CFX_ByteString Decode(CBC_BinaryBitmap* image, int32_t& e); + virtual void Init(); +}; + +#endif // XFA_FXBARCODE_QRCODE_BC_QRCODEREADER_H_ diff --git a/xfa/fxbarcode/qrcode/BC_QRCodeWriter.cpp b/xfa/fxbarcode/qrcode/BC_QRCodeWriter.cpp new file mode 100644 index 0000000000..cd4340e38c --- /dev/null +++ b/xfa/fxbarcode/qrcode/BC_QRCodeWriter.cpp @@ -0,0 +1,107 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com +// Original code is licensed as follows: +/* + * Copyright 2008 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "xfa/fxbarcode/BC_Reader.h" +#include "xfa/fxbarcode/BC_TwoDimWriter.h" +#include "xfa/fxbarcode/common/BC_CommonByteMatrix.h" +#include "xfa/fxbarcode/qrcode/BC_QRCodeReader.h" +#include "xfa/fxbarcode/qrcode/BC_QRCodeWriter.h" +#include "xfa/fxbarcode/qrcode/BC_QRCoder.h" +#include "xfa/fxbarcode/qrcode/BC_QRCoderEncoder.h" +#include "xfa/fxbarcode/qrcode/BC_QRCoderErrorCorrectionLevel.h" + +CBC_QRCodeWriter::CBC_QRCodeWriter() { + m_bFixedSize = TRUE; + m_iCorrectLevel = 1; + m_iVersion = 0; +} +CBC_QRCodeWriter::~CBC_QRCodeWriter() {} +void CBC_QRCodeWriter::ReleaseAll() { + CBC_QRCodeReader::ReleaseAll(); +} +FX_BOOL CBC_QRCodeWriter::SetVersion(int32_t version) { + if (version < 0 || version > 40) { + return FALSE; + } + m_iVersion = version; + return TRUE; +} +FX_BOOL CBC_QRCodeWriter::SetErrorCorrectionLevel(int32_t level) { + if (level < 0 || level > 3) { + return FALSE; + } + m_iCorrectLevel = level; + return TRUE; +} +uint8_t* CBC_QRCodeWriter::Encode(const CFX_WideString& contents, + int32_t ecLevel, + int32_t& outWidth, + int32_t& outHeight, + int32_t& e) { + CBC_QRCoderErrorCorrectionLevel* ec = NULL; + switch (ecLevel) { + case 0: + ec = CBC_QRCoderErrorCorrectionLevel::L; + break; + case 1: + ec = CBC_QRCoderErrorCorrectionLevel::M; + break; + case 2: + ec = CBC_QRCoderErrorCorrectionLevel::Q; + break; + case 3: + ec = CBC_QRCoderErrorCorrectionLevel::H; + break; + default: { + e = BCExceptionUnSupportEclevel; + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + } + } + CBC_QRCoder qr; + if (m_iVersion > 0 && m_iVersion < 41) { + CFX_ByteString byteStr = contents.UTF8Encode(); + CBC_QRCoderEncoder::Encode(byteStr, ec, &qr, e, m_iVersion); + } else { + CBC_QRCoderEncoder::Encode(contents, ec, &qr, e); + } + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + outWidth = qr.GetMatrixWidth(); + outHeight = qr.GetMatrixWidth(); + uint8_t* result = FX_Alloc2D(uint8_t, outWidth, outHeight); + FXSYS_memcpy(result, qr.GetMatrix()->GetArray(), outWidth * outHeight); + return result; +} +uint8_t* CBC_QRCodeWriter::Encode(const CFX_ByteString& contents, + BCFORMAT format, + int32_t& outWidth, + int32_t& outHeight, + int32_t hints, + int32_t& e) { + return NULL; +} +uint8_t* CBC_QRCodeWriter::Encode(const CFX_ByteString& contents, + BCFORMAT format, + int32_t& outWidth, + int32_t& outHeight, + int32_t& e) { + return NULL; +} diff --git a/xfa/fxbarcode/qrcode/BC_QRCodeWriter.h b/xfa/fxbarcode/qrcode/BC_QRCodeWriter.h new file mode 100644 index 0000000000..c68c6c0a3f --- /dev/null +++ b/xfa/fxbarcode/qrcode/BC_QRCodeWriter.h @@ -0,0 +1,41 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef XFA_FXBARCODE_QRCODE_BC_QRCODEWRITER_H_ +#define XFA_FXBARCODE_QRCODE_BC_QRCODEWRITER_H_ + +#include "xfa/fxbarcode/BC_TwoDimWriter.h" + +class CBC_TwoDimWriter; +class CBC_QRCodeWriter : public CBC_TwoDimWriter { + public: + CBC_QRCodeWriter(); + virtual ~CBC_QRCodeWriter(); + uint8_t* Encode(const CFX_WideString& contents, + int32_t ecLevel, + int32_t& outWidth, + int32_t& outHeight, + int32_t& e); + uint8_t* Encode(const CFX_ByteString& contents, + BCFORMAT format, + int32_t& outWidth, + int32_t& outHeight, + int32_t hints, + int32_t& e); + uint8_t* Encode(const CFX_ByteString& contents, + BCFORMAT format, + int32_t& outWidth, + int32_t& outHeight, + int32_t& e); + FX_BOOL SetVersion(int32_t version); + FX_BOOL SetErrorCorrectionLevel(int32_t level); + static void ReleaseAll(); + + private: + int32_t m_iVersion; +}; + +#endif // XFA_FXBARCODE_QRCODE_BC_QRCODEWRITER_H_ diff --git a/xfa/fxbarcode/qrcode/BC_QRCoder.cpp b/xfa/fxbarcode/qrcode/BC_QRCoder.cpp new file mode 100644 index 0000000000..9e9ad06817 --- /dev/null +++ b/xfa/fxbarcode/qrcode/BC_QRCoder.cpp @@ -0,0 +1,124 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com +// Original code is licensed as follows: +/* + * Copyright 2008 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "xfa/fxbarcode/common/BC_CommonByteMatrix.h" +#include "xfa/fxbarcode/qrcode/BC_QRCoder.h" +#include "xfa/fxbarcode/qrcode/BC_QRCoderErrorCorrectionLevel.h" +#include "xfa/fxbarcode/qrcode/BC_QRCoderMode.h" +#include "xfa/fxbarcode/utils.h" + +CBC_QRCoder::CBC_QRCoder() { + m_mode = NULL; + m_ecLevel = NULL; + m_version = -1; + m_matrixWidth = -1; + m_maskPattern = -1; + m_numTotalBytes = -1; + m_numDataBytes = -1; + m_numECBytes = -1; + m_numRSBlocks = -1; + m_matrix = NULL; +} +CBC_QRCoder::~CBC_QRCoder() { + delete m_matrix; +} +CBC_QRCoderMode* CBC_QRCoder::GetMode() { + return m_mode; +} +CBC_QRCoderErrorCorrectionLevel* CBC_QRCoder::GetECLevel() { + return m_ecLevel; +} +int32_t CBC_QRCoder::GetVersion() { + return m_version; +} +int32_t CBC_QRCoder::GetMatrixWidth() { + return m_matrixWidth; +} +int32_t CBC_QRCoder::GetMaskPattern() { + return m_maskPattern; +} +int32_t CBC_QRCoder::GetNumTotalBytes() { + return m_numTotalBytes; +} +int32_t CBC_QRCoder::GetNumDataBytes() { + return m_numDataBytes; +} +int32_t CBC_QRCoder::GetNumECBytes() { + return m_numECBytes; +} +int32_t CBC_QRCoder::GetNumRSBlocks() { + return m_numRSBlocks; +} +CBC_CommonByteMatrix* CBC_QRCoder::GetMatrix() { + return m_matrix; +} +int32_t CBC_QRCoder::At(int32_t x, int32_t y, int32_t& e) { + int32_t value = m_matrix->Get(x, y); + if (!(value == 0 || value == 1)) { + e = BCExceptionValueMustBeEither0or1; + BC_EXCEPTION_CHECK_ReturnValue(e, 0); + } + return value; +} +FX_BOOL CBC_QRCoder::IsValid() { + return m_mode && m_ecLevel && m_version != -1 && m_matrixWidth != -1 && + m_maskPattern != -1 && m_numTotalBytes != -1 && m_numDataBytes != -1 && + m_numECBytes != -1 && m_numRSBlocks != -1 && + IsValidMaskPattern(m_maskPattern) && + m_numTotalBytes == m_numDataBytes + m_numECBytes && m_matrix && + m_matrixWidth == m_matrix->GetWidth() && + m_matrix->GetWidth() == m_matrix->GetHeight(); +} +void CBC_QRCoder::SetMode(CBC_QRCoderMode* value) { + m_mode = value; +} +void CBC_QRCoder::SetECLevel(CBC_QRCoderErrorCorrectionLevel* ecLevel) { + m_ecLevel = ecLevel; +} +void CBC_QRCoder::SetVersion(int32_t version) { + m_version = version; +} +void CBC_QRCoder::SetMatrixWidth(int32_t width) { + m_matrixWidth = width; +} +void CBC_QRCoder::SetMaskPattern(int32_t pattern) { + m_maskPattern = pattern; +} +void CBC_QRCoder::SetNumDataBytes(int32_t bytes) { + m_numDataBytes = bytes; +} +void CBC_QRCoder::SetNumTotalBytes(int32_t value) { + m_numTotalBytes = value; +} +void CBC_QRCoder::SetNumRSBlocks(int32_t block) { + m_numRSBlocks = block; +} +void CBC_QRCoder::SetNumECBytes(int32_t value) { + m_numECBytes = value; +} +FX_BOOL CBC_QRCoder::IsValidMaskPattern(int32_t maskPattern) { + return maskPattern >= 0 && maskPattern < NUM_MASK_PATTERNS; +} +void CBC_QRCoder::SetMatrix(CBC_CommonByteMatrix* value) { + m_matrix = value; +} +const int32_t CBC_QRCoder::NUM_MASK_PATTERNS = 8; diff --git a/xfa/fxbarcode/qrcode/BC_QRCoder.h b/xfa/fxbarcode/qrcode/BC_QRCoder.h new file mode 100644 index 0000000000..bbf7bd4429 --- /dev/null +++ b/xfa/fxbarcode/qrcode/BC_QRCoder.h @@ -0,0 +1,57 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef XFA_FXBARCODE_QRCODE_BC_QRCODER_H_ +#define XFA_FXBARCODE_QRCODE_BC_QRCODER_H_ + +class CBC_QRCoderErrorCorrectionLevel; +class CBC_QRCoderMode; +class CBC_CommonByteMatrix; + +class CBC_QRCoder { + private: + CBC_QRCoderMode* m_mode; + CBC_QRCoderErrorCorrectionLevel* m_ecLevel; + int32_t m_version; + int32_t m_matrixWidth; + int32_t m_maskPattern; + int32_t m_numTotalBytes; + int32_t m_numDataBytes; + int32_t m_numECBytes; + int32_t m_numRSBlocks; + CBC_CommonByteMatrix* m_matrix; + + public: + static const int32_t NUM_MASK_PATTERNS; + CBC_QRCoder(); + virtual ~CBC_QRCoder(); + CBC_QRCoderMode* GetMode(); + CBC_QRCoderErrorCorrectionLevel* GetECLevel(); + int32_t GetVersion(); + int32_t GetMatrixWidth(); + int32_t GetMaskPattern(); + int32_t GetNumTotalBytes(); + int32_t GetNumDataBytes(); + int32_t GetNumECBytes(); + int32_t GetNumRSBlocks(); + CBC_CommonByteMatrix* GetMatrix(); + int32_t At(int32_t x, int32_t y, int32_t& e); + FX_BOOL IsValid(); + + void SetMode(CBC_QRCoderMode* value); + void SetECLevel(CBC_QRCoderErrorCorrectionLevel* ecLevel); + void SetVersion(int32_t version); + void SetMatrixWidth(int32_t width); + void SetMaskPattern(int32_t pattern); + void SetNumDataBytes(int32_t bytes); + void SetNumTotalBytes(int32_t value); + void SetNumECBytes(int32_t value); + void SetNumRSBlocks(int32_t block); + void SetMatrix(CBC_CommonByteMatrix* value); + static FX_BOOL IsValidMaskPattern(int32_t maskPattern); +}; + +#endif // XFA_FXBARCODE_QRCODE_BC_QRCODER_H_ diff --git a/xfa/fxbarcode/qrcode/BC_QRCoderBitVector.cpp b/xfa/fxbarcode/qrcode/BC_QRCoderBitVector.cpp new file mode 100644 index 0000000000..a225f61fbb --- /dev/null +++ b/xfa/fxbarcode/qrcode/BC_QRCoderBitVector.cpp @@ -0,0 +1,124 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com +// Original code is licensed as follows: +/* + * Copyright 2007 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "core/include/fxcrt/fx_memory.h" +#include "xfa/fxbarcode/qrcode/BC_QRCoderBitVector.h" +#include "xfa/fxbarcode/utils.h" + +CBC_QRCoderBitVector::CBC_QRCoderBitVector() { + m_sizeInBits = 0; + m_size = 32; +} +void CBC_QRCoderBitVector::Init() { + m_array = FX_Alloc(uint8_t, m_size); +} +CBC_QRCoderBitVector::~CBC_QRCoderBitVector() { + FX_Free(m_array); +} +void CBC_QRCoderBitVector::Clear() { + FX_Free(m_array); + m_sizeInBits = 0; + m_size = 32; + m_array = FX_Alloc(uint8_t, m_size); +} +int32_t CBC_QRCoderBitVector::At(int32_t index, int32_t& e) { + if (index < 0 || index >= m_sizeInBits) { + e = BCExceptionBadIndexException; + BC_EXCEPTION_CHECK_ReturnValue(e, 0); + } + int32_t value = m_array[index >> 3] & 0xff; + return (value >> (7 - (index & 0x7))) & 1; +} +int32_t CBC_QRCoderBitVector::sizeInBytes() { + return (m_sizeInBits + 7) >> 3; +} +int32_t CBC_QRCoderBitVector::Size() { + return m_sizeInBits; +} +void CBC_QRCoderBitVector::AppendBit(int32_t bit, int32_t& e) { + if (!(bit == 0 || bit == 1)) { + e = BCExceptionBadValueException; + BC_EXCEPTION_CHECK_ReturnVoid(e); + } + int32_t numBitsInLastByte = m_sizeInBits & 0x7; + if (numBitsInLastByte == 0) { + AppendByte(0); + m_sizeInBits -= 8; + } + m_array[m_sizeInBits >> 3] |= (bit << (7 - numBitsInLastByte)); + ++m_sizeInBits; +} +void CBC_QRCoderBitVector::AppendBits(int32_t value, + int32_t numBits, + int32_t& e) { + if (numBits < 0 || numBits > 32) { + e = BCExceptionBadNumBitsException; + BC_EXCEPTION_CHECK_ReturnVoid(e); + } + int32_t numBitsLeft = numBits; + while (numBitsLeft > 0) { + if ((m_sizeInBits & 0x7) == 0 && numBitsLeft >= 8) { + int32_t newByte = (value >> (numBitsLeft - 8)) & 0xff; + AppendByte(newByte); + numBitsLeft -= 8; + } else { + int32_t bit = (value >> (numBitsLeft - 1)) & 1; + AppendBit(bit, e); + BC_EXCEPTION_CHECK_ReturnVoid(e); + --numBitsLeft; + } + } +} +void CBC_QRCoderBitVector::AppendBitVector(CBC_QRCoderBitVector* bits, + int32_t& e) { + int32_t size = bits->Size(); + for (int32_t i = 0; i < size; i++) { + int32_t num = bits->At(i, e); + BC_EXCEPTION_CHECK_ReturnVoid(e); + AppendBit(num, e); + BC_EXCEPTION_CHECK_ReturnVoid(e) + } +} +void CBC_QRCoderBitVector::XOR(CBC_QRCoderBitVector* other, int32_t& e) { + if (m_sizeInBits != other->Size()) { + e = BCExceptioncanNotOperatexorOperator; + BC_EXCEPTION_CHECK_ReturnVoid(e); + } + int32_t sizeInBytes = (m_sizeInBits + 7) >> 3; + for (int32_t i = 0; i < sizeInBytes; ++i) { + m_array[i] ^= (other->GetArray())[i]; + } +} +uint8_t* CBC_QRCoderBitVector::GetArray() { + return m_array; +} +void CBC_QRCoderBitVector::AppendByte(int32_t value) { + if ((m_sizeInBits >> 3) == m_size) { + uint8_t* newArray = FX_Alloc(uint8_t, m_size << 1); + FXSYS_memcpy(newArray, m_array, m_size); + FX_Free(m_array); + m_array = newArray; + m_size = m_size << 1; + } + m_array[m_sizeInBits >> 3] = (uint8_t)value; + m_sizeInBits += 8; +} diff --git a/xfa/fxbarcode/qrcode/BC_QRCoderBitVector.h b/xfa/fxbarcode/qrcode/BC_QRCoderBitVector.h new file mode 100644 index 0000000000..7742541a06 --- /dev/null +++ b/xfa/fxbarcode/qrcode/BC_QRCoderBitVector.h @@ -0,0 +1,35 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef XFA_FXBARCODE_QRCODE_BC_QRCODERBITVECTOR_H_ +#define XFA_FXBARCODE_QRCODE_BC_QRCODERBITVECTOR_H_ + +#include <stdint.h> + +class CBC_QRCoderBitVector { + private: + int32_t m_sizeInBits; + uint8_t* m_array; + int32_t m_size; + + void AppendByte(int32_t value); + + public: + CBC_QRCoderBitVector(); + virtual ~CBC_QRCoderBitVector(); + int32_t At(int32_t index, int32_t& e); + int32_t Size(); + int32_t sizeInBytes(); + void AppendBit(int32_t bit, int32_t& e); + void AppendBits(int32_t value, int32_t numBits, int32_t& e); + void AppendBitVector(CBC_QRCoderBitVector* bits, int32_t& e); + void XOR(CBC_QRCoderBitVector* other, int32_t& e); + uint8_t* GetArray(); + void Clear(); + virtual void Init(); +}; + +#endif // XFA_FXBARCODE_QRCODE_BC_QRCODERBITVECTOR_H_ diff --git a/xfa/fxbarcode/qrcode/BC_QRCoderBlockPair.cpp b/xfa/fxbarcode/qrcode/BC_QRCoderBlockPair.cpp new file mode 100644 index 0000000000..b8a032ae68 --- /dev/null +++ b/xfa/fxbarcode/qrcode/BC_QRCoderBlockPair.cpp @@ -0,0 +1,41 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com +// Original code is licensed as follows: +/* + * Copyright 2008 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "xfa/fxbarcode/common/BC_CommonByteArray.h" +#include "xfa/fxbarcode/qrcode/BC_QRCoderBlockPair.h" + +CBC_QRCoderBlockPair::CBC_QRCoderBlockPair( + CBC_CommonByteArray* data, + CBC_CommonByteArray* errorCorrection) { + m_dataBytes = data; + m_errorCorrectionBytes = errorCorrection; +} +CBC_QRCoderBlockPair::~CBC_QRCoderBlockPair() { + delete m_dataBytes; + delete m_errorCorrectionBytes; +} +CBC_CommonByteArray* CBC_QRCoderBlockPair::GetDataBytes() { + return m_dataBytes; +} +CBC_CommonByteArray* CBC_QRCoderBlockPair::GetErrorCorrectionBytes() { + return m_errorCorrectionBytes; +} diff --git a/xfa/fxbarcode/qrcode/BC_QRCoderBlockPair.h b/xfa/fxbarcode/qrcode/BC_QRCoderBlockPair.h new file mode 100644 index 0000000000..5427436761 --- /dev/null +++ b/xfa/fxbarcode/qrcode/BC_QRCoderBlockPair.h @@ -0,0 +1,25 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef XFA_FXBARCODE_QRCODE_BC_QRCODERBLOCKPAIR_H_ +#define XFA_FXBARCODE_QRCODE_BC_QRCODERBLOCKPAIR_H_ + +class CBC_CommonByteArray; +class CBC_QRCoderBlockPair { + private: + CBC_CommonByteArray* m_dataBytes; + CBC_CommonByteArray* m_errorCorrectionBytes; + + public: + CBC_QRCoderBlockPair(CBC_CommonByteArray* data, + CBC_CommonByteArray* errorCorrection); + virtual ~CBC_QRCoderBlockPair(); + + CBC_CommonByteArray* GetDataBytes(); + CBC_CommonByteArray* GetErrorCorrectionBytes(); +}; + +#endif // XFA_FXBARCODE_QRCODE_BC_QRCODERBLOCKPAIR_H_ diff --git a/xfa/fxbarcode/qrcode/BC_QRCoderDecoder.cpp b/xfa/fxbarcode/qrcode/BC_QRCoderDecoder.cpp new file mode 100644 index 0000000000..1966146805 --- /dev/null +++ b/xfa/fxbarcode/qrcode/BC_QRCoderDecoder.cpp @@ -0,0 +1,129 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com +// Original code is licensed as follows: +/* + * Copyright 2008 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "xfa/fxbarcode/qrcode/BC_QRCoderDecoder.h" + +#include <memory> + +#include "xfa/fxbarcode/common/BC_CommonBitMatrix.h" +#include "xfa/fxbarcode/common/BC_CommonDecoderResult.h" +#include "xfa/fxbarcode/common/reedsolomon/BC_ReedSolomonDecoder.h" +#include "xfa/fxbarcode/common/reedsolomon/BC_ReedSolomonGF256.h" +#include "xfa/fxbarcode/qrcode/BC_QRBitMatrixParser.h" +#include "xfa/fxbarcode/qrcode/BC_QRCoderFormatInformation.h" +#include "xfa/fxbarcode/qrcode/BC_QRCoderVersion.h" +#include "xfa/fxbarcode/qrcode/BC_QRDataBlock.h" +#include "xfa/fxbarcode/qrcode/BC_QRDecodedBitStreamParser.h" + +CBC_QRCoderDecoder::CBC_QRCoderDecoder() { + m_rsDecoder = NULL; +} + +void CBC_QRCoderDecoder::Init() { + m_rsDecoder = new CBC_ReedSolomonDecoder(CBC_ReedSolomonGF256::QRCodeFild); +} +CBC_QRCoderDecoder::~CBC_QRCoderDecoder() { + delete m_rsDecoder; +} +CBC_CommonDecoderResult* CBC_QRCoderDecoder::Decode(FX_BOOL* image, + int32_t width, + int32_t height, + int32_t& e) { + CBC_CommonBitMatrix bits; + bits.Init(width); + for (int32_t i = 0; i < width; i++) { + for (int32_t j = 0; j < height; j++) { + if (image[i * width + j]) { + bits.Set(j, i); + } + } + } + CBC_CommonDecoderResult* cdr = Decode(&bits, height, e); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + return cdr; +} +CBC_CommonDecoderResult* CBC_QRCoderDecoder::Decode(CBC_CommonBitMatrix* bits, + int32_t byteModeDecode, + int32_t& e) { + CBC_QRBitMatrixParser parser; + parser.Init(bits, e); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + CBC_QRCoderVersion* version = parser.ReadVersion(e); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + CBC_QRCoderFormatInformation* temp = parser.ReadFormatInformation(e); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + CBC_QRCoderErrorCorrectionLevel* ecLevel = temp->GetErrorCorrectionLevel(); + std::unique_ptr<CFX_ByteArray> codewords(parser.ReadCodewords(e)); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + CFX_PtrArray* dataBlocks = + CBC_QRDataBlock::GetDataBlocks(codewords.get(), version, ecLevel, e); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + int32_t totalBytes = 0; + for (int32_t i = 0; i < dataBlocks->GetSize(); i++) { + totalBytes += ((CBC_QRDataBlock*)((*dataBlocks)[i]))->GetNumDataCodewords(); + } + CFX_ByteArray resultBytes; + for (int32_t j = 0; j < dataBlocks->GetSize(); j++) { + CBC_QRDataBlock* dataBlock = (CBC_QRDataBlock*)((*dataBlocks)[j]); + CFX_ByteArray* codewordBytes = dataBlock->GetCodewords(); + int32_t numDataCodewords = dataBlock->GetNumDataCodewords(); + CorrectErrors(codewordBytes, numDataCodewords, e); + if (e != BCExceptionNO) { + for (int32_t k = 0; k < dataBlocks->GetSize(); k++) { + delete (CBC_QRDataBlock*)(*dataBlocks)[k]; + } + dataBlocks->RemoveAll(); + delete dataBlocks; + dataBlocks = NULL; + return NULL; + } + for (int32_t i = 0; i < numDataCodewords; i++) { + resultBytes.Add((*codewordBytes)[i]); + } + } + for (int32_t k = 0; k < dataBlocks->GetSize(); k++) { + delete (CBC_QRDataBlock*)(*dataBlocks)[k]; + } + dataBlocks->RemoveAll(); + delete dataBlocks; + dataBlocks = NULL; + CBC_CommonDecoderResult* cdr = CBC_QRDecodedBitStreamParser::Decode( + &resultBytes, version, ecLevel, byteModeDecode, e); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + return cdr; +} +void CBC_QRCoderDecoder::CorrectErrors(CFX_ByteArray* codewordBytes, + int32_t numDataCodewords, + int32_t& e) { + int32_t numCodewords = codewordBytes->GetSize(); + CFX_Int32Array codewordsInts; + codewordsInts.SetSize(numCodewords); + for (int32_t i = 0; i < numCodewords; i++) { + codewordsInts[i] = (int32_t)((*codewordBytes)[i] & 0xff); + } + int32_t numECCodewords = codewordBytes->GetSize() - numDataCodewords; + m_rsDecoder->Decode(&codewordsInts, numECCodewords, e); + BC_EXCEPTION_CHECK_ReturnVoid(e); + for (int32_t k = 0; k < numDataCodewords; k++) { + (*codewordBytes)[k] = (uint8_t)codewordsInts[k]; + } +} diff --git a/xfa/fxbarcode/qrcode/BC_QRCoderDecoder.h b/xfa/fxbarcode/qrcode/BC_QRCoderDecoder.h new file mode 100644 index 0000000000..b6c381cc9d --- /dev/null +++ b/xfa/fxbarcode/qrcode/BC_QRCoderDecoder.h @@ -0,0 +1,37 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef XFA_FXBARCODE_QRCODE_BC_QRCODERDECODER_H_ +#define XFA_FXBARCODE_QRCODE_BC_QRCODERDECODER_H_ + +#include "core/include/fxcrt/fx_basic.h" + +class CBC_CommonBitMatrix; +class CBC_ReedSolomonDecoder; +class CBC_CommonDecoderResult; + +class CBC_QRCoderDecoder { + private: + CBC_ReedSolomonDecoder* m_rsDecoder; + + public: + CBC_QRCoderDecoder(); + virtual ~CBC_QRCoderDecoder(); + + CBC_CommonDecoderResult* Decode(FX_BOOL* image, + int32_t width, + int32_t height, + int32_t& e); + CBC_CommonDecoderResult* Decode(CBC_CommonBitMatrix* bits, + int32_t byteModeDecode, + int32_t& e); + void CorrectErrors(CFX_ByteArray* codewordBytes, + int32_t numDataCodewords, + int32_t& e); + virtual void Init(); +}; + +#endif // XFA_FXBARCODE_QRCODE_BC_QRCODERDECODER_H_ diff --git a/xfa/fxbarcode/qrcode/BC_QRCoderECB.cpp b/xfa/fxbarcode/qrcode/BC_QRCoderECB.cpp new file mode 100644 index 0000000000..2b5a2a6fef --- /dev/null +++ b/xfa/fxbarcode/qrcode/BC_QRCoderECB.cpp @@ -0,0 +1,35 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com +// Original code is licensed as follows: +/* + * Copyright 2007 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "xfa/fxbarcode/qrcode/BC_QRCoderECB.h" + +CBC_QRCoderECB::CBC_QRCoderECB(int32_t count, int32_t dataCodeWords) { + m_dataCodeWords = dataCodeWords; + m_count = count; +} +CBC_QRCoderECB::~CBC_QRCoderECB() {} +int32_t CBC_QRCoderECB::GetCount() { + return m_count; +} +int32_t CBC_QRCoderECB::GetDataCodeWords() { + return m_dataCodeWords; +} diff --git a/xfa/fxbarcode/qrcode/BC_QRCoderECB.h b/xfa/fxbarcode/qrcode/BC_QRCoderECB.h new file mode 100644 index 0000000000..25b0b20fe3 --- /dev/null +++ b/xfa/fxbarcode/qrcode/BC_QRCoderECB.h @@ -0,0 +1,24 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef XFA_FXBARCODE_QRCODE_BC_QRCODERECB_H_ +#define XFA_FXBARCODE_QRCODE_BC_QRCODERECB_H_ + +#include <stdint.h> + +class CBC_QRCoderECB { + private: + int32_t m_count; + int32_t m_dataCodeWords; + + public: + CBC_QRCoderECB(int32_t count, int32_t dataCodeWords); + virtual ~CBC_QRCoderECB(); + int32_t GetCount(); + int32_t GetDataCodeWords(); +}; + +#endif // XFA_FXBARCODE_QRCODE_BC_QRCODERECB_H_ diff --git a/xfa/fxbarcode/qrcode/BC_QRCoderECBlocks.cpp b/xfa/fxbarcode/qrcode/BC_QRCoderECBlocks.cpp new file mode 100644 index 0000000000..eb6d194b55 --- /dev/null +++ b/xfa/fxbarcode/qrcode/BC_QRCoderECBlocks.cpp @@ -0,0 +1,59 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com +// Original code is licensed as follows: +/* + * Copyright 2007 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "xfa/fxbarcode/qrcode/BC_QRCoderECB.h" +#include "xfa/fxbarcode/qrcode/BC_QRCoderECBlocks.h" + +CBC_QRCoderECBlocks::CBC_QRCoderECBlocks(int32_t ecCodeWordsPerBlock, + CBC_QRCoderECB* ecBlocks) { + m_ecCodeWordsPerBlock = ecCodeWordsPerBlock; + m_ecBlocks.Add(ecBlocks); +} +CBC_QRCoderECBlocks::CBC_QRCoderECBlocks(int32_t ecCodeWordsPerBlock, + CBC_QRCoderECB* ecBlocks1, + CBC_QRCoderECB* ecBlocks2) { + m_ecCodeWordsPerBlock = ecCodeWordsPerBlock; + m_ecBlocks.Add(ecBlocks1); + m_ecBlocks.Add(ecBlocks2); +} +CBC_QRCoderECBlocks::~CBC_QRCoderECBlocks() { + for (int32_t i = 0; i < m_ecBlocks.GetSize(); i++) { + delete ((CBC_QRCoderECB*)(m_ecBlocks[i])); + } + m_ecBlocks.RemoveAll(); +} +int32_t CBC_QRCoderECBlocks::GetECCodeWordsPerBlock() { + return m_ecCodeWordsPerBlock; +} +int32_t CBC_QRCoderECBlocks::GetNumBlocks() { + int32_t total = 0; + for (int32_t i = 0; i < m_ecBlocks.GetSize(); i++) { + total += ((CBC_QRCoderECB*)(m_ecBlocks[i]))->GetCount(); + } + return total; +} +int32_t CBC_QRCoderECBlocks::GetTotalECCodeWords() { + return m_ecCodeWordsPerBlock * GetNumBlocks(); +} +CFX_PtrArray* CBC_QRCoderECBlocks::GetECBlocks() { + return &m_ecBlocks; +} diff --git a/xfa/fxbarcode/qrcode/BC_QRCoderECBlocks.h b/xfa/fxbarcode/qrcode/BC_QRCoderECBlocks.h new file mode 100644 index 0000000000..c1a5b34194 --- /dev/null +++ b/xfa/fxbarcode/qrcode/BC_QRCoderECBlocks.h @@ -0,0 +1,31 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef XFA_FXBARCODE_QRCODE_BC_QRCODERECBLOCKS_H_ +#define XFA_FXBARCODE_QRCODE_BC_QRCODERECBLOCKS_H_ + +#include "core/include/fxcrt/fx_basic.h" + +class CBC_QRCoderECB; + +class CBC_QRCoderECBlocks { + private: + int32_t m_ecCodeWordsPerBlock; + CFX_PtrArray m_ecBlocks; + + public: + CBC_QRCoderECBlocks(int32_t ecCodeWordsPerBlock, CBC_QRCoderECB* ecBlocks); + CBC_QRCoderECBlocks(int32_t ecCodeWordsPerBlock, + CBC_QRCoderECB* ecBlocks1, + CBC_QRCoderECB* ecBlocks2); + virtual ~CBC_QRCoderECBlocks(); + int32_t GetECCodeWordsPerBlock(); + int32_t GetNumBlocks(); + int32_t GetTotalECCodeWords(); + CFX_PtrArray* GetECBlocks(); +}; + +#endif // XFA_FXBARCODE_QRCODE_BC_QRCODERECBLOCKS_H_ diff --git a/xfa/fxbarcode/qrcode/BC_QRCoderEncoder.cpp b/xfa/fxbarcode/qrcode/BC_QRCoderEncoder.cpp new file mode 100644 index 0000000000..0360ef0b13 --- /dev/null +++ b/xfa/fxbarcode/qrcode/BC_QRCoderEncoder.cpp @@ -0,0 +1,961 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com +// Original code is licensed as follows: +/* + * Copyright 2008 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "xfa/fxbarcode/qrcode/BC_QRCoderEncoder.h" + +#include <algorithm> +#include <memory> + +#include "xfa/fxbarcode/BC_UtilCodingConvert.h" +#include "xfa/fxbarcode/common/BC_CommonByteArray.h" +#include "xfa/fxbarcode/common/BC_CommonByteMatrix.h" +#include "xfa/fxbarcode/common/reedsolomon/BC_ReedSolomon.h" +#include "xfa/fxbarcode/common/reedsolomon/BC_ReedSolomonGF256.h" +#include "xfa/fxbarcode/qrcode/BC_QRCoder.h" +#include "xfa/fxbarcode/qrcode/BC_QRCoderBitVector.h" +#include "xfa/fxbarcode/qrcode/BC_QRCoderBlockPair.h" +#include "xfa/fxbarcode/qrcode/BC_QRCoderECBlocks.h" +#include "xfa/fxbarcode/qrcode/BC_QRCoderMaskUtil.h" +#include "xfa/fxbarcode/qrcode/BC_QRCoderMatrixUtil.h" +#include "xfa/fxbarcode/qrcode/BC_QRCoderMode.h" +#include "xfa/fxbarcode/qrcode/BC_QRCoderVersion.h" + +const int32_t CBC_QRCoderEncoder::m_alphaNumbericTable[] = { + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 36, -1, -1, -1, 37, 38, -1, -1, -1, -1, 39, 40, -1, 41, 42, 43, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 44, -1, -1, -1, -1, -1, + -1, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, -1, -1, -1, -1, -1}; + +CBC_QRCoderEncoder::CBC_QRCoderEncoder() {} +CBC_QRCoderEncoder::~CBC_QRCoderEncoder() {} +class Make_Pair { + public: + CBC_QRCoderMode* m_mode; + CFX_ByteString m_string; + + private: + Make_Pair(const Make_Pair& mode_string) {} + Make_Pair& operator=(Make_Pair& mode_string) { + if (this == &mode_string) { + return *this; + } + m_mode = mode_string.m_mode; + m_string = mode_string.m_string; + return *this; + } + + public: + Make_Pair(CBC_QRCoderMode* mode, const CFX_ByteString& str) + : m_mode(mode), m_string(str) {} + ~Make_Pair() {} +}; +void CBC_QRCoderEncoder::Encode(const CFX_ByteString& content, + CBC_QRCoderErrorCorrectionLevel* ecLevel, + CBC_QRCoder* qrCode, + int32_t& e, + int32_t versionSpecify) { + if (versionSpecify == 0) { + EncodeWithAutoVersion(content, ecLevel, qrCode, e); + BC_EXCEPTION_CHECK_ReturnVoid(e) + } else if (versionSpecify > 0 && versionSpecify <= 40) { + EncodeWithSpecifyVersion(content, ecLevel, qrCode, versionSpecify, e); + BC_EXCEPTION_CHECK_ReturnVoid(e); + } else { + e = BCExceptionVersionMust1_40; + BC_EXCEPTION_CHECK_ReturnVoid(e); + } +} +void CBC_QRCoderEncoder::AppendECI(CBC_QRCoderBitVector* bits) {} +void CBC_QRCoderEncoder::AppendDataModeLenghInfo( + CFX_PtrArray& splitResult, + CBC_QRCoderBitVector& headerAndDataBits, + CBC_QRCoderMode* tempMode, + CBC_QRCoder* qrCode, + CFX_ByteString& encoding, + int32_t& e) { + for (int32_t i = 0; i < splitResult.GetSize(); i++) { + tempMode = ((Make_Pair*)splitResult[i])->m_mode; + if (tempMode == CBC_QRCoderMode::sGBK) { + AppendModeInfo(tempMode, &headerAndDataBits, e); + BC_EXCEPTION_CHECK_ReturnVoid(e); + AppendLengthInfo(((Make_Pair*)splitResult[i])->m_string.GetLength(), + qrCode->GetVersion(), tempMode, &headerAndDataBits, e); + BC_EXCEPTION_CHECK_ReturnVoid(e); + AppendBytes(((Make_Pair*)splitResult[i])->m_string, tempMode, + &headerAndDataBits, encoding, e); + BC_EXCEPTION_CHECK_ReturnVoid(e); + } else if (tempMode == CBC_QRCoderMode::sBYTE) { + CFX_ByteArray bytes; + CBC_UtilCodingConvert::LocaleToUtf8( + ((Make_Pair*)splitResult[i])->m_string, bytes); + AppendModeInfo(tempMode, &headerAndDataBits, e); + BC_EXCEPTION_CHECK_ReturnVoid(e); + AppendLengthInfo(bytes.GetSize(), qrCode->GetVersion(), tempMode, + &headerAndDataBits, e); + BC_EXCEPTION_CHECK_ReturnVoid(e); + Append8BitBytes(bytes, &headerAndDataBits, e); + BC_EXCEPTION_CHECK_ReturnVoid(e); + } else if (tempMode == CBC_QRCoderMode::sALPHANUMERIC) { + AppendModeInfo(tempMode, &headerAndDataBits, e); + BC_EXCEPTION_CHECK_ReturnVoid(e); + AppendLengthInfo(((Make_Pair*)splitResult[i])->m_string.GetLength(), + qrCode->GetVersion(), tempMode, &headerAndDataBits, e); + BC_EXCEPTION_CHECK_ReturnVoid(e); + AppendBytes(((Make_Pair*)splitResult[i])->m_string, tempMode, + &headerAndDataBits, encoding, e); + BC_EXCEPTION_CHECK_ReturnVoid(e); + } else if (tempMode == CBC_QRCoderMode::sNUMERIC) { + AppendModeInfo(tempMode, &headerAndDataBits, e); + BC_EXCEPTION_CHECK_ReturnVoid(e); + AppendLengthInfo(((Make_Pair*)splitResult[i])->m_string.GetLength(), + qrCode->GetVersion(), tempMode, &headerAndDataBits, e); + BC_EXCEPTION_CHECK_ReturnVoid(e); + AppendBytes(((Make_Pair*)splitResult[i])->m_string, tempMode, + &headerAndDataBits, encoding, e); + BC_EXCEPTION_CHECK_ReturnVoid(e); + } else { + e = BCExceptionUnknown; + BC_EXCEPTION_CHECK_ReturnVoid(e); + } + } +} +void CBC_QRCoderEncoder::SplitString(const CFX_ByteString& content, + CFX_PtrArray& result) { + int32_t index = 0, flag = 0; + while ( + (((uint8_t)content[index] >= 0xA1 && (uint8_t)content[index] <= 0xAA) || + ((uint8_t)content[index] >= 0xB0 && (uint8_t)content[index] <= 0xFA)) && + (index < content.GetLength())) { + index += 2; + } + if (index != flag) { + result.Add( + new Make_Pair(CBC_QRCoderMode::sGBK, content.Mid(flag, index - flag))); + } + flag = index; + if (index >= content.GetLength()) { + return; + } + while ( + GetAlphaNumericCode((uint8_t)content[index]) == -1 && + !(((uint8_t)content[index] >= 0xA1 && (uint8_t)content[index] <= 0xAA) || + ((uint8_t)content[index] >= 0xB0 && (uint8_t)content[index] <= 0xFA)) && + (index < content.GetLength())) { +#if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_ + if (IsDBCSLeadByte((uint8_t)content[index])) +#else + if ((uint8_t)content[index] > 127) +#endif + { + index += 2; + } else { + index++; + } + } + if (index != flag) { + result.Add( + new Make_Pair(CBC_QRCoderMode::sBYTE, content.Mid(flag, index - flag))); + } + flag = index; + if (index >= content.GetLength()) { + return; + } + while (FXSYS_Isdigit((uint8_t)content[index]) && + (index < content.GetLength())) { + index++; + } + if (index != flag) { + result.Add(new Make_Pair(CBC_QRCoderMode::sNUMERIC, + content.Mid(flag, index - flag))); + } + flag = index; + if (index >= content.GetLength()) { + return; + } + while (GetAlphaNumericCode((uint8_t)content[index]) != -1 && + (index < content.GetLength())) { + index++; + } + if (index != flag) { + result.Add(new Make_Pair(CBC_QRCoderMode::sALPHANUMERIC, + content.Mid(flag, index - flag))); + } + flag = index; + if (index >= content.GetLength()) { + return; + } + SplitString(content.Mid(index, content.GetLength() - index), result); +} +int32_t CBC_QRCoderEncoder::GetSpanByVersion(CBC_QRCoderMode* modeFirst, + CBC_QRCoderMode* modeSecond, + int32_t versionNum, + int32_t& e) { + if (versionNum == 0) { + return 0; + } + if ((modeFirst == CBC_QRCoderMode::sALPHANUMERIC) && + (modeSecond == CBC_QRCoderMode::sBYTE)) { + if (versionNum >= 1 && versionNum <= 9) { + return 11; + } else if (versionNum >= 10 && versionNum <= 26) { + return 15; + } else if (versionNum >= 27 && versionNum <= 40) { + return 16; + } else { + e = BCExceptionNoSuchVersion; + BC_EXCEPTION_CHECK_ReturnValue(e, 0); + } + } else if ((modeSecond == CBC_QRCoderMode::sALPHANUMERIC) && + (modeFirst == CBC_QRCoderMode::sNUMERIC)) { + if (versionNum >= 1 && versionNum <= 9) { + return 13; + } else if (versionNum >= 10 && versionNum <= 26) { + return 15; + } else if (versionNum >= 27 && versionNum <= 40) { + return 17; + } else { + e = BCExceptionNoSuchVersion; + BC_EXCEPTION_CHECK_ReturnValue(e, 0); + } + } else if ((modeSecond == CBC_QRCoderMode::sBYTE) && + (modeFirst == CBC_QRCoderMode::sNUMERIC)) { + if (versionNum >= 1 && versionNum <= 9) { + return 6; + } else if (versionNum >= 10 && versionNum <= 26) { + return 8; + } else if (versionNum >= 27 && versionNum <= 40) { + return 9; + } else { + e = BCExceptionNoSuchVersion; + BC_EXCEPTION_CHECK_ReturnValue(e, 0); + } + } + return -1; +} +void CBC_QRCoderEncoder::MergeString(CFX_PtrArray& result, + int32_t versionNum, + int32_t& e) { + Make_Pair* first = NULL; + Make_Pair* second = NULL; + size_t mergeNum = 0; + int32_t i; + for (i = 0; ((i < result.GetSize()) && (i + 1 < result.GetSize())); i++) { + first = (Make_Pair*)result[i]; + second = (Make_Pair*)result[i + 1]; + if (first->m_mode == CBC_QRCoderMode::sALPHANUMERIC) { + int32_t tmp = GetSpanByVersion(CBC_QRCoderMode::sALPHANUMERIC, + CBC_QRCoderMode::sBYTE, versionNum, e); + BC_EXCEPTION_CHECK_ReturnVoid(e); + if ((second->m_mode == CBC_QRCoderMode::sBYTE) && + (first->m_string.GetLength() < tmp)) { + CFX_ByteString str = first->m_string + second->m_string; + second->m_string = str; + delete first; + result.RemoveAt(i); + i--; + mergeNum++; + } + } else if (first->m_mode == CBC_QRCoderMode::sBYTE) { + if (second->m_mode == CBC_QRCoderMode::sBYTE) { + first->m_string += second->m_string; + delete second; + result.RemoveAt(i + 1); + i--; + mergeNum++; + } + } else if (first->m_mode == CBC_QRCoderMode::sNUMERIC) { + int32_t tmp = GetSpanByVersion(CBC_QRCoderMode::sNUMERIC, + CBC_QRCoderMode::sBYTE, versionNum, e); + BC_EXCEPTION_CHECK_ReturnVoid(e); + if ((second->m_mode == CBC_QRCoderMode::sBYTE) && + (first->m_string.GetLength() < tmp)) { + CFX_ByteString str = first->m_string + second->m_string; + second->m_string = str; + delete first; + result.RemoveAt(i); + i--; + mergeNum++; + } + tmp = GetSpanByVersion(CBC_QRCoderMode::sNUMERIC, + CBC_QRCoderMode::sALPHANUMERIC, versionNum, e); + BC_EXCEPTION_CHECK_ReturnVoid(e); + if ((second->m_mode == CBC_QRCoderMode::sALPHANUMERIC) && + (first->m_string.GetLength() < tmp)) { + CFX_ByteString str = first->m_string + second->m_string; + second->m_string = str; + delete first; + result.RemoveAt(i); + i--; + mergeNum++; + } + } + } + if (mergeNum == 0) { + return; + } + MergeString(result, versionNum, e); + BC_EXCEPTION_CHECK_ReturnVoid(e); +} +void CBC_QRCoderEncoder::InitQRCode(int32_t numInputBytes, + int32_t versionNumber, + CBC_QRCoderErrorCorrectionLevel* ecLevel, + CBC_QRCoderMode* mode, + CBC_QRCoder* qrCode, + int32_t& e) { + qrCode->SetECLevel(ecLevel); + qrCode->SetMode(mode); + CBC_QRCoderVersion* version = + CBC_QRCoderVersion::GetVersionForNumber(versionNumber, e); + BC_EXCEPTION_CHECK_ReturnVoid(e); + int32_t numBytes = version->GetTotalCodeWords(); + CBC_QRCoderECBlocks* ecBlocks = version->GetECBlocksForLevel(ecLevel); + int32_t numEcBytes = ecBlocks->GetTotalECCodeWords(); + int32_t numRSBlocks = ecBlocks->GetNumBlocks(); + int32_t numDataBytes = numBytes - numEcBytes; + if (numDataBytes >= numInputBytes + 3) { + qrCode->SetVersion(versionNumber); + qrCode->SetNumTotalBytes(numBytes); + qrCode->SetNumDataBytes(numDataBytes); + qrCode->SetNumRSBlocks(numRSBlocks); + qrCode->SetNumECBytes(numEcBytes); + qrCode->SetMatrixWidth(version->GetDimensionForVersion()); + return; + } + e = BCExceptionCannotFindBlockInfo; + BC_EXCEPTION_CHECK_ReturnVoid(e); +} +void CBC_QRCoderEncoder::EncodeWithSpecifyVersion( + const CFX_ByteString& content, + CBC_QRCoderErrorCorrectionLevel* ecLevel, + CBC_QRCoder* qrCode, + int32_t versionSpecify, + int32_t& e) { + CFX_ByteString encoding = "utf8"; + CBC_QRCoderMode* mode = CBC_QRCoderMode::sBYTE; + CFX_PtrArray splitResult; + CBC_QRCoderBitVector dataBits; + dataBits.Init(); + SplitString(content, splitResult); + MergeString(splitResult, versionSpecify, e); + BC_EXCEPTION_CHECK_ReturnVoid(e) CBC_QRCoderMode* tempMode = NULL; + for (int32_t i = 0; i < splitResult.GetSize(); i++) { + AppendBytes(((Make_Pair*)splitResult[i])->m_string, + ((Make_Pair*)splitResult[i])->m_mode, &dataBits, encoding, e); + if (e != BCExceptionNO) { + for (int32_t y = 0; y < splitResult.GetSize(); y++) { + delete (Make_Pair*)splitResult[y]; + } + splitResult.RemoveAll(); + return; + } + } + int32_t numInputBytes = dataBits.sizeInBytes(); + CBC_QRCoderBitVector headerAndDataBits; + headerAndDataBits.Init(); + InitQRCode(numInputBytes, versionSpecify, ecLevel, mode, qrCode, e); + if (e != BCExceptionNO) { + for (int32_t k = 0; k < splitResult.GetSize(); k++) { + delete (Make_Pair*)splitResult[k]; + } + splitResult.RemoveAll(); + return; + } + AppendDataModeLenghInfo(splitResult, headerAndDataBits, tempMode, qrCode, + encoding, e); + if (e != BCExceptionNO) { + for (int32_t k = 0; k < splitResult.GetSize(); k++) { + delete (Make_Pair*)splitResult[k]; + } + splitResult.RemoveAll(); + return; + } + numInputBytes = headerAndDataBits.sizeInBytes(); + TerminateBits(qrCode->GetNumDataBytes(), &headerAndDataBits, e); + if (e != BCExceptionNO) { + for (int32_t k = 0; k < splitResult.GetSize(); k++) { + delete (Make_Pair*)splitResult[k]; + } + splitResult.RemoveAll(); + return; + } + for (int32_t j = 0; j < splitResult.GetSize(); j++) { + delete (Make_Pair*)splitResult[j]; + } + splitResult.RemoveAll(); + CBC_QRCoderBitVector finalBits; + finalBits.Init(); + InterleaveWithECBytes(&headerAndDataBits, qrCode->GetNumTotalBytes(), + qrCode->GetNumDataBytes(), qrCode->GetNumRSBlocks(), + &finalBits, e); + BC_EXCEPTION_CHECK_ReturnVoid(e); + std::unique_ptr<CBC_CommonByteMatrix> matrix(new CBC_CommonByteMatrix( + qrCode->GetMatrixWidth(), qrCode->GetMatrixWidth())); + matrix->Init(); + int32_t maskPattern = ChooseMaskPattern( + &finalBits, qrCode->GetECLevel(), qrCode->GetVersion(), matrix.get(), e); + BC_EXCEPTION_CHECK_ReturnVoid(e); + qrCode->SetMaskPattern(maskPattern); + CBC_QRCoderMatrixUtil::BuildMatrix(&finalBits, qrCode->GetECLevel(), + qrCode->GetVersion(), + qrCode->GetMaskPattern(), matrix.get(), e); + BC_EXCEPTION_CHECK_ReturnVoid(e); + qrCode->SetMatrix(matrix.release()); + if (!qrCode->IsValid()) { + e = BCExceptionInvalidQRCode; + BC_EXCEPTION_CHECK_ReturnVoid(e); + } +} +void CBC_QRCoderEncoder::EncodeWithAutoVersion( + const CFX_ByteString& content, + CBC_QRCoderErrorCorrectionLevel* ecLevel, + CBC_QRCoder* qrCode, + int32_t& e) { + CFX_ByteString encoding = "utf8"; + CBC_QRCoderMode* mode = CBC_QRCoderMode::sBYTE; + CFX_PtrArray splitResult; + CBC_QRCoderBitVector dataBits; + dataBits.Init(); + SplitString(content, splitResult); + MergeString(splitResult, 8, e); + BC_EXCEPTION_CHECK_ReturnVoid(e); + CBC_QRCoderMode* tempMode = NULL; + for (int32_t i = 0; i < splitResult.GetSize(); i++) { + AppendBytes(((Make_Pair*)splitResult[i])->m_string, + ((Make_Pair*)splitResult[i])->m_mode, &dataBits, encoding, e); + if (e != BCExceptionNO) { + for (int32_t l = 0; l < splitResult.GetSize(); l++) { + delete (Make_Pair*)splitResult[l]; + } + splitResult.RemoveAll(); + return; + } + } + int32_t numInputBytes = dataBits.sizeInBytes(); + InitQRCode(numInputBytes, ecLevel, mode, qrCode, e); + BC_EXCEPTION_CHECK_ReturnVoid(e) CBC_QRCoderBitVector headerAndDataBits; + headerAndDataBits.Init(); + tempMode = NULL; + int32_t versionNum = qrCode->GetVersion(); +sign: + AppendDataModeLenghInfo(splitResult, headerAndDataBits, tempMode, qrCode, + encoding, e); + if (e != BCExceptionNO) { + goto catchException; + } + numInputBytes = headerAndDataBits.sizeInBytes(); + TerminateBits(qrCode->GetNumDataBytes(), &headerAndDataBits, e); + if (e != BCExceptionNO) { + goto catchException; + } +catchException: + if (e != BCExceptionNO) { + int32_t e1 = BCExceptionNO; + InitQRCode(numInputBytes, ecLevel, mode, qrCode, e1); + if (e1 != BCExceptionNO) { + e = e1; + return; + } + versionNum++; + if (versionNum <= 40) { + headerAndDataBits.Clear(); + e = BCExceptionNO; + goto sign; + } else { + for (int32_t j = 0; j < splitResult.GetSize(); j++) { + delete (Make_Pair*)splitResult[j]; + } + splitResult.RemoveAll(); + return; + } + } + for (int32_t k = 0; k < splitResult.GetSize(); k++) { + delete (Make_Pair*)splitResult[k]; + } + splitResult.RemoveAll(); + CBC_QRCoderBitVector finalBits; + finalBits.Init(); + InterleaveWithECBytes(&headerAndDataBits, qrCode->GetNumTotalBytes(), + qrCode->GetNumDataBytes(), qrCode->GetNumRSBlocks(), + &finalBits, e); + BC_EXCEPTION_CHECK_ReturnVoid(e); + std::unique_ptr<CBC_CommonByteMatrix> matrix(new CBC_CommonByteMatrix( + qrCode->GetMatrixWidth(), qrCode->GetMatrixWidth())); + matrix->Init(); + int32_t maskPattern = ChooseMaskPattern( + &finalBits, qrCode->GetECLevel(), qrCode->GetVersion(), matrix.get(), e); + BC_EXCEPTION_CHECK_ReturnVoid(e); + qrCode->SetMaskPattern(maskPattern); + CBC_QRCoderMatrixUtil::BuildMatrix(&finalBits, qrCode->GetECLevel(), + qrCode->GetVersion(), + qrCode->GetMaskPattern(), matrix.get(), e); + BC_EXCEPTION_CHECK_ReturnVoid(e) qrCode->SetMatrix(matrix.release()); + if (!qrCode->IsValid()) { + e = BCExceptionInvalidQRCode; + BC_EXCEPTION_CHECK_ReturnVoid(e); + } +} +void CBC_QRCoderEncoder::Encode(const CFX_WideString& content, + CBC_QRCoderErrorCorrectionLevel* ecLevel, + CBC_QRCoder* qrCode, + int32_t& e) { + CFX_ByteString encoding = "utf8"; + CFX_ByteString utf8Data; + CBC_UtilCodingConvert::UnicodeToUTF8(content, utf8Data); + CBC_QRCoderMode* mode = ChooseMode(utf8Data, encoding); + CBC_QRCoderBitVector dataBits; + dataBits.Init(); + AppendBytes(utf8Data, mode, &dataBits, encoding, e); + BC_EXCEPTION_CHECK_ReturnVoid(e); + int32_t numInputBytes = dataBits.sizeInBytes(); + InitQRCode(numInputBytes, ecLevel, mode, qrCode, e); + BC_EXCEPTION_CHECK_ReturnVoid(e); + CBC_QRCoderBitVector headerAndDataBits; + headerAndDataBits.Init(); + AppendModeInfo(mode, &headerAndDataBits, e); + BC_EXCEPTION_CHECK_ReturnVoid(e); + int32_t numLetters = mode == CBC_QRCoderMode::sBYTE ? dataBits.sizeInBytes() + : content.GetLength(); + AppendLengthInfo(numLetters, qrCode->GetVersion(), mode, &headerAndDataBits, + e); + BC_EXCEPTION_CHECK_ReturnVoid(e); + headerAndDataBits.AppendBitVector(&dataBits, e); + BC_EXCEPTION_CHECK_ReturnVoid(e) + TerminateBits(qrCode->GetNumDataBytes(), &headerAndDataBits, e); + BC_EXCEPTION_CHECK_ReturnVoid(e); + CBC_QRCoderBitVector finalBits; + finalBits.Init(); + InterleaveWithECBytes(&headerAndDataBits, qrCode->GetNumTotalBytes(), + qrCode->GetNumDataBytes(), qrCode->GetNumRSBlocks(), + &finalBits, e); + BC_EXCEPTION_CHECK_ReturnVoid(e); + std::unique_ptr<CBC_CommonByteMatrix> matrix(new CBC_CommonByteMatrix( + qrCode->GetMatrixWidth(), qrCode->GetMatrixWidth())); + matrix->Init(); + int32_t maskPattern = ChooseMaskPattern( + &finalBits, qrCode->GetECLevel(), qrCode->GetVersion(), matrix.get(), e); + BC_EXCEPTION_CHECK_ReturnVoid(e); + qrCode->SetMaskPattern(maskPattern); + CBC_QRCoderMatrixUtil::BuildMatrix(&finalBits, qrCode->GetECLevel(), + qrCode->GetVersion(), + qrCode->GetMaskPattern(), matrix.get(), e); + BC_EXCEPTION_CHECK_ReturnVoid(e) qrCode->SetMatrix(matrix.release()); + if (!qrCode->IsValid()) { + e = BCExceptionInvalidQRCode; + BC_EXCEPTION_CHECK_ReturnVoid(e); + } +} +void CBC_QRCoderEncoder::TerminateBits(int32_t numDataBytes, + CBC_QRCoderBitVector* bits, + int32_t& e) { + int32_t capacity = numDataBytes << 3; + if (bits->Size() > capacity) { + e = BCExceptionDataTooMany; + BC_EXCEPTION_CHECK_ReturnVoid(e); + } + for (int32_t i = 0; i < 4 && bits->Size() < capacity; ++i) { + bits->AppendBit(0, e); + BC_EXCEPTION_CHECK_ReturnVoid(e); + } + int32_t numBitsInLastByte = bits->Size() % 8; + if (numBitsInLastByte > 0) { + int32_t numPaddingBits = 8 - numBitsInLastByte; + for (int32_t j = 0; j < numPaddingBits; ++j) { + bits->AppendBit(0, e); + BC_EXCEPTION_CHECK_ReturnVoid(e) + } + } + if (bits->Size() % 8 != 0) { + e = BCExceptionDigitLengthMustBe8; + BC_EXCEPTION_CHECK_ReturnVoid(e); + } + int32_t numPaddingBytes = numDataBytes - bits->sizeInBytes(); + for (int32_t k = 0; k < numPaddingBytes; ++k) { + if (k % 2 == 0) { + bits->AppendBits(0xec, 8, e); + BC_EXCEPTION_CHECK_ReturnVoid(e); + } else { + bits->AppendBits(0x11, 8, e); + BC_EXCEPTION_CHECK_ReturnVoid(e); + } + } + if (bits->Size() != capacity) { + e = BCExceptionBitsNotEqualCacity; + BC_EXCEPTION_CHECK_ReturnVoid(e); + } +} +int32_t CBC_QRCoderEncoder::ChooseMaskPattern( + CBC_QRCoderBitVector* bits, + CBC_QRCoderErrorCorrectionLevel* ecLevel, + int32_t version, + CBC_CommonByteMatrix* matrix, + int32_t& e) { + int32_t minPenalty = 65535; + int32_t bestMaskPattern = -1; + for (int32_t maskPattern = 0; maskPattern < CBC_QRCoder::NUM_MASK_PATTERNS; + maskPattern++) { + CBC_QRCoderMatrixUtil::BuildMatrix(bits, ecLevel, version, maskPattern, + matrix, e); + BC_EXCEPTION_CHECK_ReturnValue(e, 0); + int32_t penalty = CalculateMaskPenalty(matrix); + if (penalty < minPenalty) { + minPenalty = penalty; + bestMaskPattern = maskPattern; + } + } + return bestMaskPattern; +} +int32_t CBC_QRCoderEncoder::CalculateMaskPenalty(CBC_CommonByteMatrix* matrix) { + int32_t penalty = 0; + penalty += CBC_QRCoderMaskUtil::ApplyMaskPenaltyRule1(matrix); + penalty += CBC_QRCoderMaskUtil::ApplyMaskPenaltyRule2(matrix); + penalty += CBC_QRCoderMaskUtil::ApplyMaskPenaltyRule3(matrix); + penalty += CBC_QRCoderMaskUtil::ApplyMaskPenaltyRule4(matrix); + return penalty; +} +CBC_QRCoderMode* CBC_QRCoderEncoder::ChooseMode(const CFX_ByteString& content, + CFX_ByteString encoding) { + if (encoding.Compare("SHIFT_JIS") == 0) { + return CBC_QRCoderMode::sKANJI; + } + FX_BOOL hasNumeric = FALSE; + FX_BOOL hasAlphaNumeric = FALSE; + for (int32_t i = 0; i < content.GetLength(); i++) { + if (isdigit((uint8_t)content[i])) { + hasNumeric = TRUE; + } else if (GetAlphaNumericCode((uint8_t)content[i]) != -1) { + hasAlphaNumeric = TRUE; + } else { + return CBC_QRCoderMode::sBYTE; + } + } + if (hasAlphaNumeric) { + return CBC_QRCoderMode::sALPHANUMERIC; + } else if (hasNumeric) { + return CBC_QRCoderMode::sNUMERIC; + } + return CBC_QRCoderMode::sBYTE; +} +int32_t CBC_QRCoderEncoder::GetAlphaNumericCode(int32_t code) { + if (code < 96 && code >= 0) { + return m_alphaNumbericTable[code]; + } + return -1; +} +void CBC_QRCoderEncoder::AppendBytes(const CFX_ByteString& content, + CBC_QRCoderMode* mode, + CBC_QRCoderBitVector* bits, + CFX_ByteString encoding, + int32_t& e) { + if (mode == CBC_QRCoderMode::sNUMERIC) { + AppendNumericBytes(content, bits, e); + BC_EXCEPTION_CHECK_ReturnVoid(e); + } else if (mode == CBC_QRCoderMode::sALPHANUMERIC) { + AppendAlphaNumericBytes(content, bits, e); + BC_EXCEPTION_CHECK_ReturnVoid(e); + } else if (mode == CBC_QRCoderMode::sBYTE) { + Append8BitBytes(content, bits, encoding, e); + BC_EXCEPTION_CHECK_ReturnVoid(e); + } else if (mode == CBC_QRCoderMode::sKANJI) { + AppendKanjiBytes(content, bits, e); + BC_EXCEPTION_CHECK_ReturnVoid(e); + } else if (mode == CBC_QRCoderMode::sGBK) { + AppendGBKBytes(content, bits, e); + BC_EXCEPTION_CHECK_ReturnVoid(e); + } else { + e = BCExceptionUnsupportedMode; + BC_EXCEPTION_CHECK_ReturnVoid(e); + } +} +void CBC_QRCoderEncoder::AppendNumericBytes(const CFX_ByteString& content, + CBC_QRCoderBitVector* bits, + int32_t& e) { + int32_t length = content.GetLength(); + int32_t i = 0; + while (i < length) { + int32_t num1 = content[i] - '0'; + if (i + 2 < length) { + int32_t num2 = content[i + 1] - '0'; + int32_t num3 = content[i + 2] - '0'; + bits->AppendBits(num1 * 100 + num2 * 10 + num3, 10, e); + BC_EXCEPTION_CHECK_ReturnVoid(e) i += 3; + } else if (i + 1 < length) { + int32_t num2 = content[i + 1] - '0'; + bits->AppendBits(num1 * 10 + num2, 7, e); + BC_EXCEPTION_CHECK_ReturnVoid(e) i += 2; + } else { + bits->AppendBits(num1, 4, e); + BC_EXCEPTION_CHECK_ReturnVoid(e); + i++; + } + } +} +void CBC_QRCoderEncoder::AppendAlphaNumericBytes(const CFX_ByteString& content, + CBC_QRCoderBitVector* bits, + int32_t& e) { + int32_t length = content.GetLength(); + int32_t i = 0; + while (i < length) { + int32_t code1 = GetAlphaNumericCode(content[i]); + if (code1 == -1) { + e = BCExceptionInvalidateCharacter; + BC_EXCEPTION_CHECK_ReturnVoid(e); + } + if (i + 1 < length) { + int32_t code2 = GetAlphaNumericCode(content[i + 1]); + if (code2 == -1) { + e = BCExceptionInvalidateCharacter; + BC_EXCEPTION_CHECK_ReturnVoid(e); + } + bits->AppendBits(code1 * 45 + code2, 11, e); + BC_EXCEPTION_CHECK_ReturnVoid(e); + i += 2; + } else { + bits->AppendBits(code1, 6, e); + BC_EXCEPTION_CHECK_ReturnVoid(e) i++; + } + } +} +void CBC_QRCoderEncoder::AppendGBKBytes(const CFX_ByteString& content, + CBC_QRCoderBitVector* bits, + int32_t& e) { + int32_t length = content.GetLength(); + FX_DWORD value = 0; + for (int32_t i = 0; i < length; i += 2) { + value = (FX_DWORD)((uint8_t)content[i] << 8 | (uint8_t)content[i + 1]); + if (value <= 0xAAFE && value >= 0xA1A1) { + value -= 0xA1A1; + } else if (value <= 0xFAFE && value >= 0xB0A1) { + value -= 0xA6A1; + } else { + e = BCExceptionInvalidateCharacter; + BC_EXCEPTION_CHECK_ReturnVoid(e); + } + value = (FX_DWORD)((value >> 8) * 0x60) + (FX_DWORD)(value & 0xff); + bits->AppendBits(value, 13, e); + BC_EXCEPTION_CHECK_ReturnVoid(e); + } +} +void CBC_QRCoderEncoder::Append8BitBytes(const CFX_ByteString& content, + CBC_QRCoderBitVector* bits, + CFX_ByteString encoding, + int32_t& e) { + for (int32_t i = 0; i < content.GetLength(); i++) { + bits->AppendBits(content[i], 8, e); + BC_EXCEPTION_CHECK_ReturnVoid(e); + } +} +void CBC_QRCoderEncoder::Append8BitBytes(CFX_ByteArray& bytes, + CBC_QRCoderBitVector* bits, + int32_t& e) { + for (int32_t i = 0; i < bytes.GetSize(); i++) { + bits->AppendBits(bytes[i], 8, e); + BC_EXCEPTION_CHECK_ReturnVoid(e); + } +} +void CBC_QRCoderEncoder::AppendKanjiBytes(const CFX_ByteString& content, + CBC_QRCoderBitVector* bits, + int32_t& e) { + CFX_ByteArray bytes; + FX_DWORD value = 0; + for (int32_t i = 0; i < bytes.GetSize(); i += 2) { + value = (FX_DWORD)((uint8_t)(content[i] << 8) | (uint8_t)content[i + 1]); + if (value <= 0x9ffc && value >= 0x8140) { + value -= 0x8140; + } else if (value <= 0xebbf && value >= 0xe040) { + value -= 0xc140; + } else { + e = BCExceptionInvalidateCharacter; + BC_EXCEPTION_CHECK_ReturnVoid(e); + } + value = (FX_DWORD)((value >> 8) * 0xc0) + (FX_DWORD)(value & 0xff); + bits->AppendBits(value, 13, e); + BC_EXCEPTION_CHECK_ReturnVoid(e); + } +} +void CBC_QRCoderEncoder::InitQRCode(int32_t numInputBytes, + CBC_QRCoderErrorCorrectionLevel* ecLevel, + CBC_QRCoderMode* mode, + CBC_QRCoder* qrCode, + int32_t& e) { + qrCode->SetECLevel(ecLevel); + qrCode->SetMode(mode); + for (int32_t versionNum = 1; versionNum <= 40; versionNum++) { + CBC_QRCoderVersion* version = + CBC_QRCoderVersion::GetVersionForNumber(versionNum, e); + BC_EXCEPTION_CHECK_ReturnVoid(e); + int32_t numBytes = version->GetTotalCodeWords(); + CBC_QRCoderECBlocks* ecBlocks = version->GetECBlocksForLevel(ecLevel); + int32_t numEcBytes = ecBlocks->GetTotalECCodeWords(); + int32_t numRSBlocks = ecBlocks->GetNumBlocks(); + int32_t numDataBytes = numBytes - numEcBytes; + if (numDataBytes >= numInputBytes + 3) { + qrCode->SetVersion(versionNum); + qrCode->SetNumTotalBytes(numBytes); + qrCode->SetNumDataBytes(numDataBytes); + qrCode->SetNumRSBlocks(numRSBlocks); + qrCode->SetNumECBytes(numEcBytes); + qrCode->SetMatrixWidth(version->GetDimensionForVersion()); + return; + } + } + e = BCExceptionCannotFindBlockInfo; + BC_EXCEPTION_CHECK_ReturnVoid(e); +} +void CBC_QRCoderEncoder::AppendModeInfo(CBC_QRCoderMode* mode, + CBC_QRCoderBitVector* bits, + int32_t& e) { + bits->AppendBits(mode->GetBits(), 4, e); + if (mode == CBC_QRCoderMode::sGBK) { + bits->AppendBits(1, 4, e); + BC_EXCEPTION_CHECK_ReturnVoid(e); + } +} +void CBC_QRCoderEncoder::AppendLengthInfo(int32_t numLetters, + int32_t version, + CBC_QRCoderMode* mode, + CBC_QRCoderBitVector* bits, + int32_t& e) { + CBC_QRCoderVersion* qcv = CBC_QRCoderVersion::GetVersionForNumber(version, e); + BC_EXCEPTION_CHECK_ReturnVoid(e); + int32_t numBits = mode->GetCharacterCountBits(qcv, e); + BC_EXCEPTION_CHECK_ReturnVoid(e); + if (numBits > ((1 << numBits) - 1)) { + return; + } + if (mode == CBC_QRCoderMode::sGBK) { + bits->AppendBits(numLetters / 2, numBits, e); + BC_EXCEPTION_CHECK_ReturnVoid(e); + } + bits->AppendBits(numLetters, numBits, e); + BC_EXCEPTION_CHECK_ReturnVoid(e); +} +void CBC_QRCoderEncoder::InterleaveWithECBytes(CBC_QRCoderBitVector* bits, + int32_t numTotalBytes, + int32_t numDataBytes, + int32_t numRSBlocks, + CBC_QRCoderBitVector* result, + int32_t& e) { + if (bits->sizeInBytes() != numDataBytes) { + e = BCExceptionBitsBytesNotMatch; + BC_EXCEPTION_CHECK_ReturnVoid(e); + } + int32_t dataBytesOffset = 0; + int32_t maxNumDataBytes = 0; + int32_t maxNumEcBytes = 0; + CFX_PtrArray blocks; + int32_t i; + for (i = 0; i < numRSBlocks; i++) { + int32_t numDataBytesInBlock; + int32_t numEcBytesInBlosk; + GetNumDataBytesAndNumECBytesForBlockID(numTotalBytes, numDataBytes, + numRSBlocks, i, numDataBytesInBlock, + numEcBytesInBlosk); + CBC_CommonByteArray* dataBytes = new CBC_CommonByteArray; + dataBytes->Set(bits->GetArray(), dataBytesOffset, numDataBytesInBlock); + CBC_CommonByteArray* ecBytes = + GenerateECBytes(dataBytes, numEcBytesInBlosk, e); + BC_EXCEPTION_CHECK_ReturnVoid(e); + blocks.Add(new CBC_QRCoderBlockPair(dataBytes, ecBytes)); + maxNumDataBytes = std::max(maxNumDataBytes, dataBytes->Size()); + maxNumEcBytes = std::max(maxNumEcBytes, ecBytes->Size()); + dataBytesOffset += numDataBytesInBlock; + } + if (numDataBytes != dataBytesOffset) { + e = BCExceptionBytesNotMatchOffset; + BC_EXCEPTION_CHECK_ReturnVoid(e); + } + for (int32_t x = 0; x < maxNumDataBytes; x++) { + for (int32_t j = 0; j < blocks.GetSize(); j++) { + CBC_CommonByteArray* dataBytes = + ((CBC_QRCoderBlockPair*)blocks[j])->GetDataBytes(); + if (x < dataBytes->Size()) { + result->AppendBits(dataBytes->At(x), 8, e); + BC_EXCEPTION_CHECK_ReturnVoid(e); + } + } + } + for (int32_t y = 0; y < maxNumEcBytes; y++) { + for (int32_t l = 0; l < blocks.GetSize(); l++) { + CBC_CommonByteArray* ecBytes = + ((CBC_QRCoderBlockPair*)blocks[l])->GetErrorCorrectionBytes(); + if (y < ecBytes->Size()) { + result->AppendBits(ecBytes->At(y), 8, e); + BC_EXCEPTION_CHECK_ReturnVoid(e); + } + } + } + for (int32_t k = 0; k < blocks.GetSize(); k++) { + delete (CBC_QRCoderBlockPair*)blocks[k]; + } + if (numTotalBytes != result->sizeInBytes()) { + e = BCExceptionSizeInBytesDiffer; + BC_EXCEPTION_CHECK_ReturnVoid(e); + } +} +void CBC_QRCoderEncoder::GetNumDataBytesAndNumECBytesForBlockID( + int32_t numTotalBytes, + int32_t numDataBytes, + int32_t numRSBlocks, + int32_t blockID, + int32_t& numDataBytesInBlock, + int32_t& numECBytesInBlock) { + if (blockID >= numRSBlocks) { + return; + } + int32_t numRsBlocksInGroup2 = numTotalBytes % numRSBlocks; + int32_t numRsBlocksInGroup1 = numRSBlocks - numRsBlocksInGroup2; + int32_t numTotalBytesInGroup1 = numTotalBytes / numRSBlocks; + int32_t numTotalBytesInGroup2 = numTotalBytesInGroup1 + 1; + int32_t numDataBytesInGroup1 = numDataBytes / numRSBlocks; + int32_t numDataBytesInGroup2 = numDataBytesInGroup1 + 1; + int32_t numEcBytesInGroup1 = numTotalBytesInGroup1 - numDataBytesInGroup1; + int32_t numEcBytesInGroup2 = numTotalBytesInGroup2 - numDataBytesInGroup2; + if (blockID < numRsBlocksInGroup1) { + numDataBytesInBlock = numDataBytesInGroup1; + numECBytesInBlock = numEcBytesInGroup1; + } else { + numDataBytesInBlock = numDataBytesInGroup2; + numECBytesInBlock = numEcBytesInGroup2; + } +} +CBC_CommonByteArray* CBC_QRCoderEncoder::GenerateECBytes( + CBC_CommonByteArray* dataBytes, + int32_t numEcBytesInBlock, + int32_t& e) { + int32_t numDataBytes = dataBytes->Size(); + CFX_Int32Array toEncode; + toEncode.SetSize(numDataBytes + numEcBytesInBlock); + for (int32_t i = 0; i < numDataBytes; i++) { + toEncode[i] = (dataBytes->At(i)); + } + CBC_ReedSolomonEncoder encode(CBC_ReedSolomonGF256::QRCodeFild); + encode.Init(); + encode.Encode(&toEncode, numEcBytesInBlock, e); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + CBC_CommonByteArray* ecBytes = new CBC_CommonByteArray(numEcBytesInBlock); + for (int32_t j = 0; j < numEcBytesInBlock; j++) { + ecBytes->Set(j, toEncode[numDataBytes + j]); + } + return ecBytes; +} diff --git a/xfa/fxbarcode/qrcode/BC_QRCoderEncoder.h b/xfa/fxbarcode/qrcode/BC_QRCoderEncoder.h new file mode 100644 index 0000000000..8330dc2d1a --- /dev/null +++ b/xfa/fxbarcode/qrcode/BC_QRCoderEncoder.h @@ -0,0 +1,133 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef XFA_FXBARCODE_QRCODE_BC_QRCODERENCODER_H_ +#define XFA_FXBARCODE_QRCODE_BC_QRCODERENCODER_H_ + +#include "core/include/fxcrt/fx_basic.h" +#include "core/include/fxcrt/fx_string.h" + +class CBC_QRCoder; +class CBC_QRCoderErrorCorrectionLevel; +class CBC_QRCoderMode; +class CBC_QRCoderBitVector; +class CBC_CommonByteArray; +class CBC_CommonByteMatrix; + +class CBC_QRCoderEncoder { + private: + static const int32_t m_alphaNumbericTable[96]; + + public: + CBC_QRCoderEncoder(); + virtual ~CBC_QRCoderEncoder(); + + static void Encode(const CFX_ByteString& content, + CBC_QRCoderErrorCorrectionLevel* ecLevel, + CBC_QRCoder* qrCode, + int32_t& e, + int32_t versionSpecify = 0); + static void Encode(const CFX_WideString& content, + CBC_QRCoderErrorCorrectionLevel* ecLevel, + CBC_QRCoder* qrCode, + int32_t& e); + static void EncodeWithSpecifyVersion(const CFX_ByteString& content, + CBC_QRCoderErrorCorrectionLevel* ecLevel, + CBC_QRCoder* qrCode, + int32_t versionSpecify, + int32_t& e); + static void EncodeWithAutoVersion(const CFX_ByteString& content, + CBC_QRCoderErrorCorrectionLevel* ecLevel, + CBC_QRCoder* qrCode, + int32_t& e); + static CBC_QRCoderMode* ChooseMode(const CFX_ByteString& content, + CFX_ByteString encoding); + static int32_t GetAlphaNumericCode(int32_t code); + static void AppendECI(CBC_QRCoderBitVector* bits); + static void AppendBytes(const CFX_ByteString& content, + CBC_QRCoderMode* mode, + CBC_QRCoderBitVector* bits, + CFX_ByteString encoding, + int32_t& e); + static void AppendNumericBytes(const CFX_ByteString& content, + CBC_QRCoderBitVector* bits, + int32_t& e); + static void AppendAlphaNumericBytes(const CFX_ByteString& content, + CBC_QRCoderBitVector* bits, + int32_t& e); + static void Append8BitBytes(const CFX_ByteString& content, + CBC_QRCoderBitVector* bits, + CFX_ByteString encoding, + int32_t& e); + static void Append8BitBytes(CFX_ByteArray& bytes, + CBC_QRCoderBitVector* bits, + int32_t& e); + static void AppendKanjiBytes(const CFX_ByteString& content, + CBC_QRCoderBitVector* bits, + int32_t& e); + static void AppendGBKBytes(const CFX_ByteString& content, + CBC_QRCoderBitVector* bits, + int32_t& e); + static void InitQRCode(int32_t numInputBytes, + int32_t versionNumber, + CBC_QRCoderErrorCorrectionLevel* ecLevel, + CBC_QRCoderMode* mode, + CBC_QRCoder* qrCode, + int32_t& e); + static void InitQRCode(int32_t numInputBytes, + CBC_QRCoderErrorCorrectionLevel* ecLevel, + CBC_QRCoderMode* mode, + CBC_QRCoder* qrCode, + int32_t& e); + static void AppendModeInfo(CBC_QRCoderMode* mode, + CBC_QRCoderBitVector* bits, + int32_t& e); + static void AppendLengthInfo(int32_t numLetters, + int32_t version, + CBC_QRCoderMode* mode, + CBC_QRCoderBitVector* bits, + int32_t& e); + + static void InterleaveWithECBytes(CBC_QRCoderBitVector* bits, + int32_t numTotalBytes, + int32_t numDataBytes, + int32_t numRSBlocks, + CBC_QRCoderBitVector* result, + int32_t& e); + static void GetNumDataBytesAndNumECBytesForBlockID( + int32_t numTotalBytes, + int32_t numDataBytes, + int32_t numRSBlocks, + int32_t blockID, + int32_t& numDataBytesInBlock, + int32_t& numECBytesInBlocks); + static CBC_CommonByteArray* GenerateECBytes(CBC_CommonByteArray* dataBytes, + int32_t numEcBytesInBlock, + int32_t& e); + static int32_t ChooseMaskPattern(CBC_QRCoderBitVector* bits, + CBC_QRCoderErrorCorrectionLevel* ecLevel, + int32_t version, + CBC_CommonByteMatrix* matrix, + int32_t& e); + static int32_t CalculateMaskPenalty(CBC_CommonByteMatrix* matrix); + static void TerminateBits(int32_t numDataBytes, + CBC_QRCoderBitVector* bits, + int32_t& e); + static int32_t GetSpanByVersion(CBC_QRCoderMode* modeFirst, + CBC_QRCoderMode* modeSecond, + int32_t versionNum, + int32_t& e); + static void MergeString(CFX_PtrArray& result, int32_t versionNum, int32_t& e); + static void SplitString(const CFX_ByteString& content, CFX_PtrArray& result); + static void AppendDataModeLenghInfo(CFX_PtrArray& splitResult, + CBC_QRCoderBitVector& headerAndDataBits, + CBC_QRCoderMode* tempMode, + CBC_QRCoder* qrCode, + CFX_ByteString& encoding, + int32_t& e); +}; + +#endif // XFA_FXBARCODE_QRCODE_BC_QRCODERENCODER_H_ diff --git a/xfa/fxbarcode/qrcode/BC_QRCoderErrorCorrectionLevel.cpp b/xfa/fxbarcode/qrcode/BC_QRCoderErrorCorrectionLevel.cpp new file mode 100644 index 0000000000..a1ce747b40 --- /dev/null +++ b/xfa/fxbarcode/qrcode/BC_QRCoderErrorCorrectionLevel.cpp @@ -0,0 +1,92 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com +// Original code is licensed as follows: +/* + * Copyright 2007 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "xfa/fxbarcode/qrcode/BC_QRCoderErrorCorrectionLevel.h" + +CBC_QRCoderErrorCorrectionLevel* CBC_QRCoderErrorCorrectionLevel::L = NULL; +CBC_QRCoderErrorCorrectionLevel* CBC_QRCoderErrorCorrectionLevel::M = NULL; +CBC_QRCoderErrorCorrectionLevel* CBC_QRCoderErrorCorrectionLevel::Q = NULL; +CBC_QRCoderErrorCorrectionLevel* CBC_QRCoderErrorCorrectionLevel::H = NULL; + +CBC_QRCoderErrorCorrectionLevel::CBC_QRCoderErrorCorrectionLevel( + int32_t ordinal, + int32_t bits, + FX_CHAR* name) { + m_name += name; + m_ordinal = ordinal; + m_bits = bits; +} +CBC_QRCoderErrorCorrectionLevel::~CBC_QRCoderErrorCorrectionLevel() {} +void CBC_QRCoderErrorCorrectionLevel::Initialize() { + L = new CBC_QRCoderErrorCorrectionLevel(0, 0x01, (FX_CHAR*)"L"); + M = new CBC_QRCoderErrorCorrectionLevel(1, 0x00, (FX_CHAR*)"M"); + Q = new CBC_QRCoderErrorCorrectionLevel(2, 0x03, (FX_CHAR*)"Q"); + H = new CBC_QRCoderErrorCorrectionLevel(3, 0x02, (FX_CHAR*)"H"); +} +void CBC_QRCoderErrorCorrectionLevel::Finalize() { + delete L; + delete M; + delete Q; + delete H; +} +int32_t CBC_QRCoderErrorCorrectionLevel::Ordinal() { + return m_ordinal; +} +int32_t CBC_QRCoderErrorCorrectionLevel::GetBits() { + return m_bits; +} +CFX_ByteString CBC_QRCoderErrorCorrectionLevel::GetName() { + return m_name; +} +CBC_QRCoderErrorCorrectionLevel* CBC_QRCoderErrorCorrectionLevel::ForBits( + int32_t bits) { + switch (bits) { + case 0x00: + return M; + case 0x01: + return L; + case 0x02: + return H; + case 0x03: + return Q; + default: + return NULL; + } +} +void CBC_QRCoderErrorCorrectionLevel::Destroy() { + if (L) { + delete CBC_QRCoderErrorCorrectionLevel::L; + L = NULL; + } + if (M) { + delete CBC_QRCoderErrorCorrectionLevel::M; + M = NULL; + } + if (H) { + delete CBC_QRCoderErrorCorrectionLevel::H; + H = NULL; + } + if (Q) { + delete CBC_QRCoderErrorCorrectionLevel::Q; + Q = NULL; + } +} diff --git a/xfa/fxbarcode/qrcode/BC_QRCoderErrorCorrectionLevel.h b/xfa/fxbarcode/qrcode/BC_QRCoderErrorCorrectionLevel.h new file mode 100644 index 0000000000..377137ae91 --- /dev/null +++ b/xfa/fxbarcode/qrcode/BC_QRCoderErrorCorrectionLevel.h @@ -0,0 +1,35 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef XFA_FXBARCODE_QRCODE_BC_QRCODERERRORCORRECTIONLEVEL_H_ +#define XFA_FXBARCODE_QRCODE_BC_QRCODERERRORCORRECTIONLEVEL_H_ + +#include "core/include/fxcrt/fx_string.h" + +class CBC_QRCoderErrorCorrectionLevel { + private: + int32_t m_ordinal; + int32_t m_bits; + CFX_ByteString m_name; + CBC_QRCoderErrorCorrectionLevel(int32_t ordinal, int32_t bits, FX_CHAR* name); + CBC_QRCoderErrorCorrectionLevel(); + + public: + static CBC_QRCoderErrorCorrectionLevel* L; + static CBC_QRCoderErrorCorrectionLevel* M; + static CBC_QRCoderErrorCorrectionLevel* Q; + static CBC_QRCoderErrorCorrectionLevel* H; + virtual ~CBC_QRCoderErrorCorrectionLevel(); + static void Initialize(); + static void Finalize(); + int32_t Ordinal(); + int32_t GetBits(); + CFX_ByteString GetName(); + static void Destroy(); + static CBC_QRCoderErrorCorrectionLevel* ForBits(int32_t bits); +}; + +#endif // XFA_FXBARCODE_QRCODE_BC_QRCODERERRORCORRECTIONLEVEL_H_ diff --git a/xfa/fxbarcode/qrcode/BC_QRCoderFormatInformation.cpp b/xfa/fxbarcode/qrcode/BC_QRCoderFormatInformation.cpp new file mode 100644 index 0000000000..da647a9c53 --- /dev/null +++ b/xfa/fxbarcode/qrcode/BC_QRCoderFormatInformation.cpp @@ -0,0 +1,95 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com +// Original code is licensed as follows: +/* + * Copyright 2007 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "xfa/fxbarcode/qrcode/BC_QRCoderErrorCorrectionLevel.h" +#include "xfa/fxbarcode/qrcode/BC_QRCoderFormatInformation.h" +#include "xfa/fxbarcode/utils.h" + +const int32_t CBC_QRCoderFormatInformation::FORMAT_INFO_MASK_QR = 0X5412; +const int32_t CBC_QRCoderFormatInformation::FORMAT_INFO_DECODE_LOOKUP[32][2] = { + {0x5412, 0x00}, {0x5125, 0x01}, {0x5E7C, 0x02}, {0x5B4B, 0x03}, + {0x45F9, 0x04}, {0x40CE, 0x05}, {0x4F97, 0x06}, {0x4AA0, 0x07}, + {0x77C4, 0x08}, {0x72F3, 0x09}, {0x7DAA, 0x0A}, {0x789D, 0x0B}, + {0x662F, 0x0C}, {0x6318, 0x0D}, {0x6C41, 0x0E}, {0x6976, 0x0F}, + {0x1689, 0x10}, {0x13BE, 0x11}, {0x1CE7, 0x12}, {0x19D0, 0x13}, + {0x0762, 0x14}, {0x0255, 0x15}, {0x0D0C, 0x16}, {0x083B, 0x17}, + {0x355F, 0x18}, {0x3068, 0x19}, {0x3F31, 0x1A}, {0x3A06, 0x1B}, + {0x24B4, 0x1C}, {0x2183, 0x1D}, {0x2EDA, 0x1E}, {0x2BED, 0x1F}, +}; +const int32_t CBC_QRCoderFormatInformation::BITS_SET_IN_HALF_BYTE[] = { + 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4}; + +CBC_QRCoderFormatInformation::CBC_QRCoderFormatInformation(int32_t formatInfo) { + m_errorCorrectLevl = + CBC_QRCoderErrorCorrectionLevel::ForBits((formatInfo >> 3) & 0x03); + m_dataMask = (uint8_t)(formatInfo & 0x07); +} +CBC_QRCoderFormatInformation::~CBC_QRCoderFormatInformation() {} +int32_t CBC_QRCoderFormatInformation::NumBitsDiffering(int32_t a, int32_t b) { + a ^= b; + return BITS_SET_IN_HALF_BYTE[a & 0x0F] + + BITS_SET_IN_HALF_BYTE[(a >> 4) & 0x0F] + + BITS_SET_IN_HALF_BYTE[(a >> 8) & 0x0F] + + BITS_SET_IN_HALF_BYTE[(a >> 12) & 0x0F] + + BITS_SET_IN_HALF_BYTE[(a >> 16) & 0x0F] + + BITS_SET_IN_HALF_BYTE[(a >> 20) & 0x0F] + + BITS_SET_IN_HALF_BYTE[(a >> 24) & 0x0F] + + BITS_SET_IN_HALF_BYTE[(a >> 28) & 0x0F]; +} +uint8_t CBC_QRCoderFormatInformation::GetDataMask() { + return m_dataMask; +} +CBC_QRCoderErrorCorrectionLevel* +CBC_QRCoderFormatInformation::GetErrorCorrectionLevel() { + return m_errorCorrectLevl; +} +CBC_QRCoderFormatInformation* +CBC_QRCoderFormatInformation::DecodeFormatInformation( + int32_t maskedFormatInfo) { + CBC_QRCoderFormatInformation* formatInfo = + DoDecodeFormatInformation(maskedFormatInfo); + if (formatInfo) + return formatInfo; + return DoDecodeFormatInformation(maskedFormatInfo ^ FORMAT_INFO_MASK_QR); +} +CBC_QRCoderFormatInformation* +CBC_QRCoderFormatInformation::DoDecodeFormatInformation( + int32_t maskedFormatInfo) { + int32_t bestDifference = (int32_t)FXSYS_nan(); + int32_t bestFormatInfo = 0; + for (int32_t i = 0; i < 32; i++) { + int32_t const* decodeInfo = &FORMAT_INFO_DECODE_LOOKUP[i][0]; + int32_t targetInfo = decodeInfo[0]; + if (targetInfo == maskedFormatInfo) { + return new CBC_QRCoderFormatInformation(decodeInfo[1]); + } + int32_t bitsDifference = NumBitsDiffering(maskedFormatInfo, targetInfo); + if (bitsDifference < bestDifference) { + bestFormatInfo = decodeInfo[1]; + bestDifference = bitsDifference; + } + } + if (bestDifference <= 3) { + return new CBC_QRCoderFormatInformation(bestFormatInfo); + } + return NULL; +} diff --git a/xfa/fxbarcode/qrcode/BC_QRCoderFormatInformation.h b/xfa/fxbarcode/qrcode/BC_QRCoderFormatInformation.h new file mode 100644 index 0000000000..8f1590172e --- /dev/null +++ b/xfa/fxbarcode/qrcode/BC_QRCoderFormatInformation.h @@ -0,0 +1,32 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef XFA_FXBARCODE_QRCODE_BC_QRCODERFORMATINFORMATION_H_ +#define XFA_FXBARCODE_QRCODE_BC_QRCODERFORMATINFORMATION_H_ + +class CBC_QRCoderErrorCorrectionLevel; +class CBC_QRCoderFormatInformation { + private: + static const int32_t FORMAT_INFO_MASK_QR; + static const int32_t FORMAT_INFO_DECODE_LOOKUP[32][2]; + static const int32_t BITS_SET_IN_HALF_BYTE[16]; + CBC_QRCoderErrorCorrectionLevel* m_errorCorrectLevl; + uint8_t m_dataMask; + + public: + CBC_QRCoderFormatInformation(int32_t formatInfo); + virtual ~CBC_QRCoderFormatInformation(); + uint8_t GetDataMask(); + CBC_QRCoderErrorCorrectionLevel* GetErrorCorrectionLevel(); + + static int32_t NumBitsDiffering(int32_t a, int32_t b); + static CBC_QRCoderFormatInformation* DecodeFormatInformation( + int32_t maskedFormatInfo); + static CBC_QRCoderFormatInformation* DoDecodeFormatInformation( + int32_t maskedFormatInfo); +}; + +#endif // XFA_FXBARCODE_QRCODE_BC_QRCODERFORMATINFORMATION_H_ diff --git a/xfa/fxbarcode/qrcode/BC_QRCoderMaskUtil.cpp b/xfa/fxbarcode/qrcode/BC_QRCoderMaskUtil.cpp new file mode 100644 index 0000000000..4d845c4b07 --- /dev/null +++ b/xfa/fxbarcode/qrcode/BC_QRCoderMaskUtil.cpp @@ -0,0 +1,198 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com +// Original code is licensed as follows: +/* + * Copyright 2008 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "xfa/fxbarcode/common/BC_CommonByteMatrix.h" +#include "xfa/fxbarcode/qrcode/BC_QRCoder.h" +#include "xfa/fxbarcode/qrcode/BC_QRCoderErrorCorrectionLevel.h" +#include "xfa/fxbarcode/qrcode/BC_QRCoderMaskUtil.h" +#include "xfa/fxbarcode/utils.h" + +CBC_QRCoderMaskUtil::CBC_QRCoderMaskUtil() {} +CBC_QRCoderMaskUtil::~CBC_QRCoderMaskUtil() {} +int32_t CBC_QRCoderMaskUtil::ApplyMaskPenaltyRule1( + CBC_CommonByteMatrix* matrix) { + return ApplyMaskPenaltyRule1Internal(matrix, TRUE) + + ApplyMaskPenaltyRule1Internal(matrix, FALSE); +} + +int32_t CBC_QRCoderMaskUtil::ApplyMaskPenaltyRule2( + CBC_CommonByteMatrix* matrix) { + int32_t penalty = 0; + uint8_t* array = matrix->GetArray(); + int32_t width = matrix->GetWidth(); + int32_t height = matrix->GetHeight(); + for (int32_t y = 0; y < height - 1; y++) { + for (int32_t x = 0; x < width - 1; x++) { + int32_t value = array[y * width + x]; + if (value == array[y * width + x + 1] && + value == array[(y + 1) * width + x] && + value == array[(y + 1) * width + x + 1]) { + penalty++; + } + } + } + return 3 * penalty; +} + +int32_t CBC_QRCoderMaskUtil::ApplyMaskPenaltyRule3( + CBC_CommonByteMatrix* matrix) { + int32_t penalty = 0; + uint8_t* array = matrix->GetArray(); + int32_t width = matrix->GetWidth(); + int32_t height = matrix->GetHeight(); + for (int32_t y = 0; y < height; ++y) { + for (int32_t x = 0; x < width; ++x) { + if (x == 0 && + ((y >= 0 && y <= 6) || (y >= height - 7 && y <= height - 1))) { + continue; + } + if (x == width - 7 && (y >= 0 && y <= 6)) { + continue; + } + if (y == 0 && + ((x >= 0 && x <= 6) || (x >= width - 7 && x <= width - 1))) { + continue; + } + if (y == height - 7 && (x >= 0 && x <= 6)) { + continue; + } + if (x + 6 < width && array[y * width + x] == 1 && + array[y * width + x + 1] == 0 && array[y * width + x + 2] == 1 && + array[y * width + x + 3] == 1 && array[y * width + x + 4] == 1 && + array[y * width + x + 5] == 0 && array[y * width + x + 6] == 1 && + ((x + 10 < width && array[y * width + x + 7] == 0 && + array[y * width + x + 8] == 0 && array[y * width + x + 9] == 0 && + array[y * width + x + 10] == 0) || + (x - 4 >= 0 && array[y * width + x - 1] == 0 && + array[y * width + x - 2] == 0 && array[y * width + x - 3] == 0 && + array[y * width + x - 4] == 0))) { + penalty += 40; + } + if (y + 6 < height && array[y * width + x] == 1 && + array[(y + 1) * width + x] == 0 && array[(y + 2) * width + x] == 1 && + array[(y + 3) * width + x] == 1 && array[(y + 4) * width + x] == 1 && + array[(y + 5) * width + x] == 0 && array[(y + 6) * width + x] == 1 && + ((y + 10 < height && array[(y + 7) * width + x] == 0 && + array[(y + 8) * width + x] == 0 && + array[(y + 9) * width + x] == 0 && + array[(y + 10) * width + x] == 0) || + (y - 4 >= 0 && array[(y - 1) * width + x] == 0 && + array[(y - 2) * width + x] == 0 && + array[(y - 3) * width + x] == 0 && + array[(y - 4) * width + x] == 0))) { + penalty += 40; + } + } + } + return penalty; +} +int32_t CBC_QRCoderMaskUtil::ApplyMaskPenaltyRule4( + CBC_CommonByteMatrix* matrix) { + int32_t numDarkCells = 0; + uint8_t* array = matrix->GetArray(); + int32_t width = matrix->GetWidth(); + int32_t height = matrix->GetHeight(); + for (int32_t y = 0; y < height; ++y) { + for (int32_t x = 0; x < width; ++x) { + if (array[y * width + x] == 1) { + numDarkCells += 1; + } + } + } + int32_t numTotalCells = matrix->GetHeight() * matrix->GetWidth(); + double darkRatio = (double)numDarkCells / numTotalCells; + return abs((int32_t)(darkRatio * 100 - 50) / 5) * 5 * 10; +} +FX_BOOL CBC_QRCoderMaskUtil::GetDataMaskBit(int32_t maskPattern, + int32_t x, + int32_t y, + int32_t& e) { + if (!CBC_QRCoder::IsValidMaskPattern(maskPattern)) { + e = (BCExceptionInvalidateMaskPattern); + BC_EXCEPTION_CHECK_ReturnValue(e, FALSE); + } + int32_t intermediate = 0, temp = 0; + switch (maskPattern) { + case 0: + intermediate = (y + x) & 0x1; + break; + case 1: + intermediate = y & 0x1; + break; + case 2: + intermediate = x % 3; + break; + case 3: + intermediate = (y + x) % 3; + break; + case 4: + intermediate = ((y >> 1) + (x / 3)) & 0x1; + break; + case 5: + temp = y * x; + intermediate = (temp & 0x1) + (temp % 3); + break; + case 6: + temp = y * x; + intermediate = (((temp & 0x1) + (temp % 3)) & 0x1); + break; + case 7: + temp = y * x; + intermediate = (((temp % 3) + ((y + x) & 0x1)) & 0x1); + break; + default: { + e = BCExceptionInvalidateMaskPattern; + BC_EXCEPTION_CHECK_ReturnValue(e, FALSE); + } + } + return intermediate == 0; +} +int32_t CBC_QRCoderMaskUtil::ApplyMaskPenaltyRule1Internal( + CBC_CommonByteMatrix* matrix, + FX_BOOL isHorizontal) { + int32_t penalty = 0; + int32_t numSameBitCells = 0; + int32_t prevBit = -1; + int32_t width = matrix->GetWidth(); + int32_t height = matrix->GetHeight(); + int32_t iLimit = isHorizontal ? height : width; + int32_t jLimit = isHorizontal ? width : height; + uint8_t* array = matrix->GetArray(); + for (int32_t i = 0; i < iLimit; ++i) { + for (int32_t j = 0; j < jLimit; ++j) { + int32_t bit = isHorizontal ? array[i * width + j] : array[j * width + i]; + if (bit == prevBit) { + numSameBitCells += 1; + if (numSameBitCells == 5) { + penalty += 3; + } else if (numSameBitCells > 5) { + penalty += 1; + } + } else { + numSameBitCells = 1; + prevBit = bit; + } + } + numSameBitCells = 0; + } + return penalty; +} diff --git a/xfa/fxbarcode/qrcode/BC_QRCoderMaskUtil.h b/xfa/fxbarcode/qrcode/BC_QRCoderMaskUtil.h new file mode 100644 index 0000000000..35032a3aaf --- /dev/null +++ b/xfa/fxbarcode/qrcode/BC_QRCoderMaskUtil.h @@ -0,0 +1,27 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef XFA_FXBARCODE_QRCODE_BC_QRCODERMASKUTIL_H_ +#define XFA_FXBARCODE_QRCODE_BC_QRCODERMASKUTIL_H_ +class CBC_CommonByteMatrix; +class CBC_QRCoderMaskUtil { + public: + CBC_QRCoderMaskUtil(); + virtual ~CBC_QRCoderMaskUtil(); + static FX_BOOL GetDataMaskBit(int32_t maskPattern, + int32_t x, + int32_t y, + int32_t& e); + + static int32_t ApplyMaskPenaltyRule1(CBC_CommonByteMatrix* matrix); + static int32_t ApplyMaskPenaltyRule2(CBC_CommonByteMatrix* matrix); + static int32_t ApplyMaskPenaltyRule3(CBC_CommonByteMatrix* matrix); + static int32_t ApplyMaskPenaltyRule4(CBC_CommonByteMatrix* matrix); + static int32_t ApplyMaskPenaltyRule1Internal(CBC_CommonByteMatrix* matrix, + FX_BOOL isHorizontal); +}; + +#endif // XFA_FXBARCODE_QRCODE_BC_QRCODERMASKUTIL_H_ diff --git a/xfa/fxbarcode/qrcode/BC_QRCoderMatrixUtil.cpp b/xfa/fxbarcode/qrcode/BC_QRCoderMatrixUtil.cpp new file mode 100644 index 0000000000..65cf0365cb --- /dev/null +++ b/xfa/fxbarcode/qrcode/BC_QRCoderMatrixUtil.cpp @@ -0,0 +1,474 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com +// Original code is licensed as follows: +/* + * Copyright 2008 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "xfa/fxbarcode/common/BC_CommonByteMatrix.h" +#include "xfa/fxbarcode/qrcode/BC_QRCoder.h" +#include "xfa/fxbarcode/qrcode/BC_QRCoderBitVector.h" +#include "xfa/fxbarcode/qrcode/BC_QRCoderErrorCorrectionLevel.h" +#include "xfa/fxbarcode/qrcode/BC_QRCoderMaskUtil.h" +#include "xfa/fxbarcode/qrcode/BC_QRCoderMatrixUtil.h" +#include "xfa/fxbarcode/utils.h" + +const int32_t CBC_QRCoderMatrixUtil::POSITION_DETECTION_PATTERN[7][7] = { + {1, 1, 1, 1, 1, 1, 1}, {1, 0, 0, 0, 0, 0, 1}, {1, 0, 1, 1, 1, 0, 1}, + {1, 0, 1, 1, 1, 0, 1}, {1, 0, 1, 1, 1, 0, 1}, {1, 0, 0, 0, 0, 0, 1}, + {1, 1, 1, 1, 1, 1, 1}}; +const int32_t CBC_QRCoderMatrixUtil::HORIZONTAL_SEPARATION_PATTERN[1][8] = { + {0, 0, 0, 0, 0, 0, 0, 0}}; +const int32_t CBC_QRCoderMatrixUtil::VERTICAL_SEPARATION_PATTERN[7][1] = { + {0}, {0}, {0}, {0}, {0}, {0}, {0}}; +const int32_t CBC_QRCoderMatrixUtil::POSITION_ADJUSTMENT_PATTERN[5][5] = { + {1, 1, 1, 1, 1}, + {1, 0, 0, 0, 1}, + {1, 0, 1, 0, 1}, + {1, 0, 0, 0, 1}, + {1, 1, 1, 1, 1}}; +const int32_t + CBC_QRCoderMatrixUtil::POSITION_ADJUSTMENT_PATTERN_COORDINATE_TABLE[40][7] = + // NOLINTNEXTLINE + { + {-1, -1, -1, -1, -1, -1, -1}, {6, 18, -1, -1, -1, -1, -1}, + {6, 22, -1, -1, -1, -1, -1}, {6, 26, -1, -1, -1, -1, -1}, + {6, 30, -1, -1, -1, -1, -1}, {6, 34, -1, -1, -1, -1, -1}, + {6, 22, 38, -1, -1, -1, -1}, {6, 24, 42, -1, -1, -1, -1}, + {6, 26, 46, -1, -1, -1, -1}, {6, 28, 50, -1, -1, -1, -1}, + {6, 30, 54, -1, -1, -1, -1}, {6, 32, 58, -1, -1, -1, -1}, + {6, 34, 62, -1, -1, -1, -1}, {6, 26, 46, 66, -1, -1, -1}, + {6, 26, 48, 70, -1, -1, -1}, {6, 26, 50, 74, -1, -1, -1}, + {6, 30, 54, 78, -1, -1, -1}, {6, 30, 56, 82, -1, -1, -1}, + {6, 30, 58, 86, -1, -1, -1}, {6, 34, 62, 90, -1, -1, -1}, + {6, 28, 50, 72, 94, -1, -1}, {6, 26, 50, 74, 98, -1, -1}, + {6, 30, 54, 78, 102, -1, -1}, {6, 28, 54, 80, 106, -1, -1}, + {6, 32, 58, 84, 110, -1, -1}, {6, 30, 58, 86, 114, -1, -1}, + {6, 34, 62, 90, 118, -1, -1}, {6, 26, 50, 74, 98, 122, -1}, + {6, 30, 54, 78, 102, 126, -1}, {6, 26, 52, 78, 104, 130, -1}, + {6, 30, 56, 82, 108, 134, -1}, {6, 34, 60, 86, 112, 138, -1}, + {6, 30, 58, 86, 114, 142, -1}, {6, 34, 62, 90, 118, 146, -1}, + {6, 30, 54, 78, 102, 126, 150}, {6, 24, 50, 76, 102, 128, 154}, + {6, 28, 54, 80, 106, 132, 158}, {6, 32, 58, 84, 110, 136, 162}, + {6, 26, 54, 82, 110, 138, 166}, {6, 30, 58, 86, 114, 142, 170}, +}; +const int32_t CBC_QRCoderMatrixUtil::TYPE_INFO_COORDINATES[15][2] = { + {8, 0}, {8, 1}, {8, 2}, {8, 3}, {8, 4}, {8, 5}, {8, 7}, {8, 8}, + {7, 8}, {5, 8}, {4, 8}, {3, 8}, {2, 8}, {1, 8}, {0, 8}, +}; +const int32_t CBC_QRCoderMatrixUtil::VERSION_INFO_POLY = 0x1f25; +const int32_t CBC_QRCoderMatrixUtil::TYPE_INFO_POLY = 0x0537; +const int32_t CBC_QRCoderMatrixUtil::TYPE_INFO_MASK_PATTERN = 0x5412; + +void CBC_QRCoderMatrixUtil::ClearMatrix(CBC_CommonByteMatrix* matrix, + int32_t& e) { + if (matrix == NULL) { + e = BCExceptionNullPointer; + BC_EXCEPTION_CHECK_ReturnVoid(e); + } + matrix->clear((uint8_t)-1); +} +void CBC_QRCoderMatrixUtil::BuildMatrix( + CBC_QRCoderBitVector* dataBits, + CBC_QRCoderErrorCorrectionLevel* ecLevel, + int32_t version, + int32_t maskPattern, + CBC_CommonByteMatrix* matrix, + int32_t& e) { + if (matrix == NULL) { + e = BCExceptionNullPointer; + BC_EXCEPTION_CHECK_ReturnVoid(e); + } + ClearMatrix(matrix, e); + BC_EXCEPTION_CHECK_ReturnVoid(e); + EmbedBasicPatterns(version, matrix, e); + BC_EXCEPTION_CHECK_ReturnVoid(e); + EmbedTypeInfo(ecLevel, maskPattern, matrix, e); + BC_EXCEPTION_CHECK_ReturnVoid(e); + MaybeEmbedVersionInfo(version, matrix, e); + BC_EXCEPTION_CHECK_ReturnVoid(e); + EmbedDataBits(dataBits, maskPattern, matrix, e); + BC_EXCEPTION_CHECK_ReturnVoid(e); +} +void CBC_QRCoderMatrixUtil::EmbedBasicPatterns(int32_t version, + CBC_CommonByteMatrix* matrix, + int32_t& e) { + if (matrix == NULL) { + e = BCExceptionNullPointer; + BC_EXCEPTION_CHECK_ReturnVoid(e); + } + EmbedPositionDetectionPatternsAndSeparators(matrix, e); + BC_EXCEPTION_CHECK_ReturnVoid(e); + EmbedDarkDotAtLeftBottomCorner(matrix, e); + BC_EXCEPTION_CHECK_ReturnVoid(e); + MaybeEmbedPositionAdjustmentPatterns(version, matrix, e); + BC_EXCEPTION_CHECK_ReturnVoid(e); + EmbedTimingPatterns(matrix, e); + BC_EXCEPTION_CHECK_ReturnVoid(e); +} +void CBC_QRCoderMatrixUtil::EmbedTypeInfo( + CBC_QRCoderErrorCorrectionLevel* ecLevel, + int32_t maskPattern, + CBC_CommonByteMatrix* matrix, + int32_t& e) { + if (matrix == NULL) { + e = BCExceptionNullPointer; + BC_EXCEPTION_CHECK_ReturnVoid(e); + } + CBC_QRCoderBitVector typeInfoBits; + typeInfoBits.Init(); + MakeTypeInfoBits(ecLevel, maskPattern, &typeInfoBits, e); + BC_EXCEPTION_CHECK_ReturnVoid(e); + for (int32_t i = 0; i < typeInfoBits.Size(); i++) { + int32_t bit = typeInfoBits.At(typeInfoBits.Size() - 1 - i, e); + BC_EXCEPTION_CHECK_ReturnVoid(e); + int32_t x1 = TYPE_INFO_COORDINATES[i][0]; + int32_t y1 = TYPE_INFO_COORDINATES[i][1]; + matrix->Set(x1, y1, bit); + if (i < 8) { + int32_t x2 = matrix->GetWidth() - i - 1; + int32_t y2 = 8; + matrix->Set(x2, y2, bit); + } else { + int32_t x2 = 8; + int32_t y2 = matrix->GetHeight() - 7 + (i - 8); + matrix->Set(x2, y2, bit); + } + } +} +void CBC_QRCoderMatrixUtil::MaybeEmbedVersionInfo(int32_t version, + CBC_CommonByteMatrix* matrix, + int32_t& e) { + if (matrix == NULL) { + e = BCExceptionNullPointer; + BC_EXCEPTION_CHECK_ReturnVoid(e); + } + if (version < 7) { + return; + } + CBC_QRCoderBitVector versionInfoBits; + versionInfoBits.Init(); + MakeVersionInfoBits(version, &versionInfoBits, e); + BC_EXCEPTION_CHECK_ReturnVoid(e); + int32_t bitIndex = 6 * 3 - 1; + for (int32_t i = 0; i < 6; i++) { + for (int32_t j = 0; j < 3; j++) { + int32_t bit = versionInfoBits.At(bitIndex, e); + BC_EXCEPTION_CHECK_ReturnVoid(e); + bitIndex--; + matrix->Set(i, matrix->GetHeight() - 11 + j, bit); + matrix->Set(matrix->GetHeight() - 11 + j, i, bit); + } + } +} +void CBC_QRCoderMatrixUtil::EmbedDataBits(CBC_QRCoderBitVector* dataBits, + int32_t maskPattern, + CBC_CommonByteMatrix* matrix, + int32_t& e) { + if (matrix == NULL || dataBits == NULL) { + e = BCExceptionNullPointer; + BC_EXCEPTION_CHECK_ReturnVoid(e); + } + int32_t bitIndex = 0; + int32_t direction = -1; + int32_t x = matrix->GetWidth() - 1; + int32_t y = matrix->GetHeight() - 1; + while (x > 0) { + if (x == 6) { + x -= 1; + } + while (y >= 0 && y < matrix->GetHeight()) { + if (y == 6) { + y += direction; + continue; + } + for (int32_t i = 0; i < 2; i++) { + int32_t xx = x - i; + if (!IsEmpty(matrix->Get(xx, y))) { + continue; + } + int32_t bit; + if (bitIndex < dataBits->Size()) { + bit = dataBits->At(bitIndex, e); + BC_EXCEPTION_CHECK_ReturnVoid(e); + bitIndex++; + } else { + bit = 0; + } + if (maskPattern != -1) { + FX_BOOL bol = + CBC_QRCoderMaskUtil::GetDataMaskBit(maskPattern, xx, y, e); + BC_EXCEPTION_CHECK_ReturnVoid(e); + if (bol) { + bit ^= 0x01; + } + } + matrix->Set(xx, y, bit); + } + y += direction; + } + direction = -direction; + y += direction; + x -= 2; + } + if (bitIndex != dataBits->Size()) { + return; + } +} +int32_t CBC_QRCoderMatrixUtil::CalculateBCHCode(int32_t value, int32_t poly) { + int32_t msbSetInPoly = FindMSBSet(poly); + value <<= msbSetInPoly - 1; + while (FindMSBSet(value) >= msbSetInPoly) { + value ^= poly << (FindMSBSet(value) - msbSetInPoly); + } + return value; +} +void CBC_QRCoderMatrixUtil::MakeTypeInfoBits( + CBC_QRCoderErrorCorrectionLevel* ecLevel, + int32_t maskPattern, + CBC_QRCoderBitVector* bits, + int32_t& e) { + if (bits == NULL) { + e = BCExceptionNullPointer; + BC_EXCEPTION_CHECK_ReturnVoid(e); + } + if (!CBC_QRCoder::IsValidMaskPattern(maskPattern)) { + e = BCExceptionBadMask; + BC_EXCEPTION_CHECK_ReturnVoid(e); + } + int32_t typeInfo = (ecLevel->GetBits() << 3) | maskPattern; + BC_EXCEPTION_CHECK_ReturnVoid(e); + bits->AppendBits(typeInfo, 5, e); + int32_t bchCode = CalculateBCHCode(typeInfo, TYPE_INFO_POLY); + BC_EXCEPTION_CHECK_ReturnVoid(e); + bits->AppendBits(bchCode, 10, e); + CBC_QRCoderBitVector maskBits; + maskBits.Init(); + maskBits.AppendBits(TYPE_INFO_MASK_PATTERN, 15, e); + BC_EXCEPTION_CHECK_ReturnVoid(e); + bits->XOR(&maskBits, e); + BC_EXCEPTION_CHECK_ReturnVoid(e); + if (bits->Size() != 15) { + e = BCExceptionBitSizeNot15; + BC_EXCEPTION_CHECK_ReturnVoid(e); + } +} +void CBC_QRCoderMatrixUtil::MakeVersionInfoBits(int32_t version, + CBC_QRCoderBitVector* bits, + int32_t& e) { + if (bits == NULL) { + e = BCExceptionNullPointer; + BC_EXCEPTION_CHECK_ReturnVoid(e); + } + bits->AppendBits(version, 6, e); + BC_EXCEPTION_CHECK_ReturnVoid(e); + int32_t bchCode = CalculateBCHCode(version, VERSION_INFO_POLY); + bits->AppendBits(bchCode, 12, e); + BC_EXCEPTION_CHECK_ReturnVoid(e); + if (bits->Size() != 18) { + e = BCExceptionBitSizeNot18; + BC_EXCEPTION_CHECK_ReturnVoid(e); + } +} +FX_BOOL CBC_QRCoderMatrixUtil::IsEmpty(int32_t value) { + return (uint8_t)value == 0xff; +} +FX_BOOL CBC_QRCoderMatrixUtil::IsValidValue(int32_t value) { + return ((uint8_t)value == 0xff || (uint8_t)value == 0x00 || + (uint8_t)value == 0x01); +} +void CBC_QRCoderMatrixUtil::EmbedTimingPatterns(CBC_CommonByteMatrix* matrix, + int32_t& e) { + if (matrix == NULL) { + e = BCExceptionNullPointer; + BC_EXCEPTION_CHECK_ReturnVoid(e); + } + for (int32_t i = 8; i < matrix->GetWidth() - 8; i++) { + int32_t bit = (i + 1) % 2; + if (!IsValidValue(matrix->Get(i, 6))) { + e = BCExceptionInvalidateImageData; + BC_EXCEPTION_CHECK_ReturnVoid(e); + } + if (IsEmpty(matrix->Get(i, 6))) { + matrix->Set(i, 6, bit); + } + if (!IsValidValue(matrix->Get(6, i))) { + e = BCExceptionInvalidateImageData; + BC_EXCEPTION_CHECK_ReturnVoid(e); + } + if (IsEmpty(matrix->Get(6, i))) { + matrix->Set(6, i, bit); + } + } +} +void CBC_QRCoderMatrixUtil::EmbedDarkDotAtLeftBottomCorner( + CBC_CommonByteMatrix* matrix, + int32_t& e) { + if (matrix == NULL) { + e = BCExceptionNullPointer; + BC_EXCEPTION_CHECK_ReturnVoid(e); + } + if (matrix->Get(8, matrix->GetHeight() - 8) == 0) { + e = BCExceptionHeight_8BeZero; + BC_EXCEPTION_CHECK_ReturnVoid(e); + } + matrix->Set(8, matrix->GetHeight() - 8, 1); +} +void CBC_QRCoderMatrixUtil::EmbedHorizontalSeparationPattern( + int32_t xStart, + int32_t yStart, + CBC_CommonByteMatrix* matrix, + int32_t& e) { + if (matrix == NULL) { + e = BCExceptionNullPointer; + BC_EXCEPTION_CHECK_ReturnVoid(e); + } + for (int32_t x = 0; x < 8; x++) { + if (!IsEmpty(matrix->Get(xStart + x, yStart))) { + e = BCExceptionInvalidateData; + BC_EXCEPTION_CHECK_ReturnVoid(e) + } + matrix->Set(xStart + x, yStart, HORIZONTAL_SEPARATION_PATTERN[0][x]); + } +} +void CBC_QRCoderMatrixUtil::EmbedVerticalSeparationPattern( + int32_t xStart, + int32_t yStart, + CBC_CommonByteMatrix* matrix, + int32_t& e) { + if (matrix == NULL) { + e = BCExceptionNullPointer; + BC_EXCEPTION_CHECK_ReturnVoid(e); + } + for (int32_t y = 0; y < 7; y++) { + if (!IsEmpty(matrix->Get(xStart, yStart + y))) { + e = BCExceptionInvalidateData; + BC_EXCEPTION_CHECK_ReturnVoid(e); + } + matrix->Set(xStart, yStart + y, VERTICAL_SEPARATION_PATTERN[y][0]); + } +} +void CBC_QRCoderMatrixUtil::EmbedPositionAdjustmentPattern( + int32_t xStart, + int32_t yStart, + CBC_CommonByteMatrix* matrix, + int32_t& e) { + if (matrix == NULL) { + e = BCExceptionNullPointer; + BC_EXCEPTION_CHECK_ReturnVoid(e); + } + for (int32_t y = 0; y < 5; y++) { + for (int32_t x = 0; x < 5; x++) { + if (!IsEmpty(matrix->Get(xStart + x, y + yStart))) { + e = BCExceptionInvalidateData; + BC_EXCEPTION_CHECK_ReturnVoid(e); + } + matrix->Set(xStart + x, yStart + y, POSITION_ADJUSTMENT_PATTERN[y][x]); + } + } +} +void CBC_QRCoderMatrixUtil::EmbedPositionDetectionPattern( + int32_t xStart, + int32_t yStart, + CBC_CommonByteMatrix* matrix, + int32_t& e) { + if (matrix == NULL) { + e = BCExceptionNullPointer; + BC_EXCEPTION_CHECK_ReturnVoid(e); + } + for (int32_t y = 0; y < 7; y++) { + for (int32_t x = 0; x < 7; x++) { + if (!IsEmpty(matrix->Get(xStart + x, yStart + y))) { + e = BCExceptionInvalidateData; + BC_EXCEPTION_CHECK_ReturnVoid(e); + } + matrix->Set(xStart + x, yStart + y, POSITION_DETECTION_PATTERN[y][x]); + } + } +} +void CBC_QRCoderMatrixUtil::EmbedPositionDetectionPatternsAndSeparators( + CBC_CommonByteMatrix* matrix, + int32_t& e) { + if (matrix == NULL) { + e = BCExceptionNullPointer; + BC_EXCEPTION_CHECK_ReturnVoid(e); + } + int32_t pdpWidth = 7; + EmbedPositionDetectionPattern(0, 0, matrix, e); + BC_EXCEPTION_CHECK_ReturnVoid(e); + EmbedPositionDetectionPattern(matrix->GetWidth() - pdpWidth, 0, matrix, e); + BC_EXCEPTION_CHECK_ReturnVoid(e); + EmbedPositionDetectionPattern(0, matrix->GetWidth() - pdpWidth, matrix, e); + BC_EXCEPTION_CHECK_ReturnVoid(e); + int32_t hspWidth = 8; + EmbedHorizontalSeparationPattern(0, hspWidth - 1, matrix, e); + BC_EXCEPTION_CHECK_ReturnVoid(e); + EmbedHorizontalSeparationPattern(matrix->GetWidth() - hspWidth, hspWidth - 1, + matrix, e); + BC_EXCEPTION_CHECK_ReturnVoid(e); + EmbedHorizontalSeparationPattern(0, matrix->GetWidth() - hspWidth, matrix, e); + BC_EXCEPTION_CHECK_ReturnVoid(e); + int32_t vspSize = 7; + EmbedVerticalSeparationPattern(vspSize, 0, matrix, e); + BC_EXCEPTION_CHECK_ReturnVoid(e); + EmbedVerticalSeparationPattern(matrix->GetHeight() - vspSize - 1, 0, matrix, + e); + BC_EXCEPTION_CHECK_ReturnVoid(e); + EmbedVerticalSeparationPattern(vspSize, matrix->GetHeight() - vspSize, matrix, + e); + BC_EXCEPTION_CHECK_ReturnVoid(e); +} +void CBC_QRCoderMatrixUtil::MaybeEmbedPositionAdjustmentPatterns( + int32_t version, + CBC_CommonByteMatrix* matrix, + int32_t& e) { + if (matrix == NULL) { + e = BCExceptionNullPointer; + BC_EXCEPTION_CHECK_ReturnVoid(e); + } + if (version < 2) { + return; + } + int32_t index = version - 1; + int32_t const* coordinates = + &(POSITION_ADJUSTMENT_PATTERN_COORDINATE_TABLE[index][0]); + int32_t numCoordinate = 7; + for (int32_t i = 0; i < numCoordinate; i++) { + for (int32_t j = 0; j < numCoordinate; j++) { + int32_t y = coordinates[i]; + int32_t x = coordinates[j]; + if (x == -1 || y == -1) { + continue; + } + if (IsEmpty(matrix->Get(x, y))) { + EmbedPositionAdjustmentPattern(x - 2, y - 2, matrix, e); + BC_EXCEPTION_CHECK_ReturnVoid(e); + } + } + } +} +int32_t CBC_QRCoderMatrixUtil::FindMSBSet(int32_t value) { + int32_t numDigits = 0; + while (value != 0) { + value >>= 1; + ++numDigits; + } + return numDigits; +} +CBC_QRCoderMatrixUtil::CBC_QRCoderMatrixUtil() {} +CBC_QRCoderMatrixUtil::~CBC_QRCoderMatrixUtil() {} diff --git a/xfa/fxbarcode/qrcode/BC_QRCoderMatrixUtil.h b/xfa/fxbarcode/qrcode/BC_QRCoderMatrixUtil.h new file mode 100644 index 0000000000..feb0bb491c --- /dev/null +++ b/xfa/fxbarcode/qrcode/BC_QRCoderMatrixUtil.h @@ -0,0 +1,87 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef XFA_FXBARCODE_QRCODE_BC_QRCODERMATRIXUTIL_H_ +#define XFA_FXBARCODE_QRCODE_BC_QRCODERMATRIXUTIL_H_ + +class CBC_CommonByteMatrix; +class CBC_QRCoderErrorCorrectionLevel; +class CBC_QRCoderBitVector; +class CBC_QRCoderMatrixUtil { + private: + static const int32_t POSITION_DETECTION_PATTERN[7][7]; + static const int32_t VERTICAL_SEPARATION_PATTERN[7][1]; + static const int32_t HORIZONTAL_SEPARATION_PATTERN[1][8]; + static const int32_t POSITION_ADJUSTMENT_PATTERN[5][5]; + static const int32_t POSITION_ADJUSTMENT_PATTERN_COORDINATE_TABLE[40][7]; + static const int32_t TYPE_INFO_COORDINATES[15][2]; + static const int32_t VERSION_INFO_POLY; + static const int32_t TYPE_INFO_POLY; + static const int32_t TYPE_INFO_MASK_PATTERN; + + public: + CBC_QRCoderMatrixUtil(); + virtual ~CBC_QRCoderMatrixUtil(); + static void ClearMatrix(CBC_CommonByteMatrix* matrix, int32_t& e); + static void BuildMatrix(CBC_QRCoderBitVector* dataBits, + CBC_QRCoderErrorCorrectionLevel* ecLevel, + int32_t version, + int32_t maskPattern, + CBC_CommonByteMatrix* matrix, + int32_t& e); + static void EmbedBasicPatterns(int32_t version, + CBC_CommonByteMatrix* matrix, + int32_t& e); + static void EmbedTypeInfo(CBC_QRCoderErrorCorrectionLevel* ecLevel, + int32_t maskPattern, + CBC_CommonByteMatrix* matrix, + int32_t& e); + static void EmbedDataBits(CBC_QRCoderBitVector* dataBits, + int32_t maskPattern, + CBC_CommonByteMatrix* matrix, + int32_t& e); + static void MaybeEmbedVersionInfo(int32_t version, + CBC_CommonByteMatrix* matrix, + int32_t& e); + static int32_t FindMSBSet(int32_t value); + static int32_t CalculateBCHCode(int32_t code, int32_t poly); + static void MakeTypeInfoBits(CBC_QRCoderErrorCorrectionLevel* ecLevel, + int32_t maskPattern, + CBC_QRCoderBitVector* bits, + int32_t& e); + static void MakeVersionInfoBits(int32_t version, + CBC_QRCoderBitVector* bits, + int32_t& e); + static FX_BOOL IsEmpty(int32_t value); + static FX_BOOL IsValidValue(int32_t value); + static void EmbedTimingPatterns(CBC_CommonByteMatrix* matrix, int32_t& e); + static void EmbedDarkDotAtLeftBottomCorner(CBC_CommonByteMatrix* matrix, + int32_t& e); + static void EmbedHorizontalSeparationPattern(int32_t xStart, + int32_t yStart, + CBC_CommonByteMatrix* matrix, + int32_t& e); + static void EmbedVerticalSeparationPattern(int32_t xStart, + int32_t yStart, + CBC_CommonByteMatrix* matrix, + int32_t& e); + static void EmbedPositionAdjustmentPattern(int32_t xStart, + int32_t yStart, + CBC_CommonByteMatrix* matrix, + int32_t& e); + static void EmbedPositionDetectionPattern(int32_t xStart, + int32_t yStart, + CBC_CommonByteMatrix* matrix, + int32_t& e); + static void EmbedPositionDetectionPatternsAndSeparators( + CBC_CommonByteMatrix* matrix, + int32_t& e); + static void MaybeEmbedPositionAdjustmentPatterns(int32_t version, + CBC_CommonByteMatrix* matrix, + int32_t& e); +}; + +#endif // XFA_FXBARCODE_QRCODE_BC_QRCODERMATRIXUTIL_H_ diff --git a/xfa/fxbarcode/qrcode/BC_QRCoderMode.cpp b/xfa/fxbarcode/qrcode/BC_QRCoderMode.cpp new file mode 100644 index 0000000000..2abdab55a5 --- /dev/null +++ b/xfa/fxbarcode/qrcode/BC_QRCoderMode.cpp @@ -0,0 +1,179 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com +// Original code is licensed as follows: +/* + * Copyright 2007 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "xfa/fxbarcode/qrcode/BC_QRCoderMode.h" +#include "xfa/fxbarcode/qrcode/BC_QRCoderVersion.h" +#include "xfa/fxbarcode/utils.h" + +CBC_QRCoderMode* CBC_QRCoderMode::sBYTE = NULL; +CBC_QRCoderMode* CBC_QRCoderMode::sNUMERIC = NULL; +CBC_QRCoderMode* CBC_QRCoderMode::sALPHANUMERIC = NULL; +CBC_QRCoderMode* CBC_QRCoderMode::sKANJI = NULL; +CBC_QRCoderMode* CBC_QRCoderMode::sECI = NULL; +CBC_QRCoderMode* CBC_QRCoderMode::sGBK = NULL; +CBC_QRCoderMode* CBC_QRCoderMode::sTERMINATOR = NULL; +CBC_QRCoderMode* CBC_QRCoderMode::sFNC1_FIRST_POSITION = NULL; +CBC_QRCoderMode* CBC_QRCoderMode::sFNC1_SECOND_POSITION = NULL; +CBC_QRCoderMode* CBC_QRCoderMode::sSTRUCTURED_APPEND = NULL; + +CBC_QRCoderMode::CBC_QRCoderMode(int32_t* characterCountBitsForVersions, + int32_t x1, + int32_t x2, + int32_t x3, + int32_t bits, + CFX_ByteString name) { + m_characterCountBitsForVersions = characterCountBitsForVersions; + if (m_characterCountBitsForVersions) { + m_characterCountBitsForVersions[0] = x1; + m_characterCountBitsForVersions[1] = x2; + m_characterCountBitsForVersions[2] = x3; + } + m_name += name; + m_bits = bits; +} +CBC_QRCoderMode::~CBC_QRCoderMode() { + FX_Free(m_characterCountBitsForVersions); +} +void CBC_QRCoderMode::Initialize() { + sBYTE = new CBC_QRCoderMode(FX_Alloc(int32_t, 3), 8, 16, 16, 0x4, "BYTE"); + sALPHANUMERIC = + new CBC_QRCoderMode(FX_Alloc(int32_t, 3), 9, 11, 13, 0x2, "ALPHANUMERIC"); + sECI = new CBC_QRCoderMode(NULL, 0, 0, 0, 0x7, "ECI"); + sKANJI = new CBC_QRCoderMode(FX_Alloc(int32_t, 3), 8, 10, 12, 0x8, "KANJI"); + sNUMERIC = + new CBC_QRCoderMode(FX_Alloc(int32_t, 3), 10, 12, 14, 0x1, "NUMERIC"); + sGBK = new CBC_QRCoderMode(FX_Alloc(int32_t, 3), 8, 10, 12, 0x0D, "GBK"); + sTERMINATOR = + new CBC_QRCoderMode(FX_Alloc(int32_t, 3), 0, 0, 0, 0x00, "TERMINATOR"); + sFNC1_FIRST_POSITION = + new CBC_QRCoderMode(NULL, 0, 0, 0, 0x05, "FNC1_FIRST_POSITION"); + sFNC1_SECOND_POSITION = + new CBC_QRCoderMode(NULL, 0, 0, 0, 0x09, "FNC1_SECOND_POSITION"); + sSTRUCTURED_APPEND = new CBC_QRCoderMode(FX_Alloc(int32_t, 3), 0, 0, 0, 0x03, + "STRUCTURED_APPEND"); +} +void CBC_QRCoderMode::Finalize() { + delete sBYTE; + delete sALPHANUMERIC; + delete sECI; + delete sKANJI; + delete sNUMERIC; + delete sGBK; + delete sTERMINATOR; + delete sFNC1_FIRST_POSITION; + delete sFNC1_SECOND_POSITION; + delete sSTRUCTURED_APPEND; +} +CBC_QRCoderMode* CBC_QRCoderMode::ForBits(int32_t bits, int32_t& e) { + switch (bits) { + case 0x0: + return sTERMINATOR; + case 0x1: + return sNUMERIC; + case 0x2: + return sALPHANUMERIC; + case 0x3: + return sSTRUCTURED_APPEND; + case 0x4: + return sBYTE; + case 0x5: + return sFNC1_FIRST_POSITION; + case 0x7: + return sECI; + case 0x8: + return sKANJI; + case 0x9: + return sFNC1_SECOND_POSITION; + case 0x0D: + return sGBK; + default: { + e = BCExceptionUnsupportedMode; + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + } + } + return NULL; +} +int32_t CBC_QRCoderMode::GetBits() { + return m_bits; +} +CFX_ByteString CBC_QRCoderMode::GetName() { + return m_name; +} +int32_t CBC_QRCoderMode::GetCharacterCountBits(CBC_QRCoderVersion* version, + int32_t& e) { + if (m_characterCountBitsForVersions == NULL) { + e = BCExceptionCharacterNotThisMode; + BC_EXCEPTION_CHECK_ReturnValue(e, 0); + } + int32_t number = version->GetVersionNumber(); + int32_t offset; + if (number <= 9) { + offset = 0; + } else if (number <= 26) { + offset = 1; + } else { + offset = 2; + } + return m_characterCountBitsForVersions[offset]; +} +void CBC_QRCoderMode::Destroy() { + if (sBYTE) { + delete CBC_QRCoderMode::sBYTE; + sBYTE = NULL; + } + if (sNUMERIC) { + delete CBC_QRCoderMode::sNUMERIC; + sNUMERIC = NULL; + } + if (sALPHANUMERIC) { + delete CBC_QRCoderMode::sALPHANUMERIC; + sALPHANUMERIC = NULL; + } + if (sKANJI) { + delete CBC_QRCoderMode::sKANJI; + sKANJI = NULL; + } + if (sECI) { + delete CBC_QRCoderMode::sECI; + sECI = NULL; + } + if (sGBK) { + delete CBC_QRCoderMode::sGBK; + sGBK = NULL; + } + if (sTERMINATOR) { + delete CBC_QRCoderMode::sTERMINATOR; + sTERMINATOR = NULL; + } + if (sFNC1_FIRST_POSITION) { + delete CBC_QRCoderMode::sFNC1_FIRST_POSITION; + sFNC1_FIRST_POSITION = NULL; + } + if (sFNC1_SECOND_POSITION) { + delete CBC_QRCoderMode::sFNC1_SECOND_POSITION; + sFNC1_SECOND_POSITION = NULL; + } + if (sSTRUCTURED_APPEND) { + delete CBC_QRCoderMode::sSTRUCTURED_APPEND; + sSTRUCTURED_APPEND = NULL; + } +} diff --git a/xfa/fxbarcode/qrcode/BC_QRCoderMode.h b/xfa/fxbarcode/qrcode/BC_QRCoderMode.h new file mode 100644 index 0000000000..e36f7a13b5 --- /dev/null +++ b/xfa/fxbarcode/qrcode/BC_QRCoderMode.h @@ -0,0 +1,51 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef XFA_FXBARCODE_QRCODE_BC_QRCODERMODE_H_ +#define XFA_FXBARCODE_QRCODE_BC_QRCODERMODE_H_ + +#include <stdint.h> + +#include "core/include/fxcrt/fx_string.h" + +class CBC_QRCoderVersion; + +class CBC_QRCoderMode { + private: + int32_t* m_characterCountBitsForVersions; + int32_t m_bits; + CFX_ByteString m_name; + CBC_QRCoderMode(int32_t* characterCountBitsForVersions, + int32_t x1, + int32_t x2, + int32_t x3, + int32_t bits, + CFX_ByteString name); + CBC_QRCoderMode(); + + public: + static CBC_QRCoderMode* sBYTE; + static CBC_QRCoderMode* sNUMERIC; + static CBC_QRCoderMode* sALPHANUMERIC; + static CBC_QRCoderMode* sKANJI; + static CBC_QRCoderMode* sECI; + static CBC_QRCoderMode* sGBK; + static CBC_QRCoderMode* sTERMINATOR; + static CBC_QRCoderMode* sFNC1_FIRST_POSITION; + static CBC_QRCoderMode* sFNC1_SECOND_POSITION; + static CBC_QRCoderMode* sSTRUCTURED_APPEND; + virtual ~CBC_QRCoderMode(); + + static void Initialize(); + static void Finalize(); + static CBC_QRCoderMode* ForBits(int32_t bits, int32_t& e); + int32_t GetCharacterCountBits(CBC_QRCoderVersion* version, int32_t& e); + int32_t GetBits(); + CFX_ByteString GetName(); + static void Destroy(); +}; + +#endif // XFA_FXBARCODE_QRCODE_BC_QRCODERMODE_H_ diff --git a/xfa/fxbarcode/qrcode/BC_QRCoderVersion.cpp b/xfa/fxbarcode/qrcode/BC_QRCoderVersion.cpp new file mode 100644 index 0000000000..1ff557ede2 --- /dev/null +++ b/xfa/fxbarcode/qrcode/BC_QRCoderVersion.cpp @@ -0,0 +1,769 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com +// Original code is licensed as follows: +/* + * Copyright 2007 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "xfa/fxbarcode/common/BC_CommonBitMatrix.h" +#include "xfa/fxbarcode/qrcode/BC_QRCoderBitVector.h" +#include "xfa/fxbarcode/qrcode/BC_QRCoderECB.h" +#include "xfa/fxbarcode/qrcode/BC_QRCoderECBlocks.h" +#include "xfa/fxbarcode/qrcode/BC_QRCoderErrorCorrectionLevel.h" +#include "xfa/fxbarcode/qrcode/BC_QRCoderFormatInformation.h" +#include "xfa/fxbarcode/qrcode/BC_QRCoderVersion.h" +#include "xfa/fxbarcode/utils.h" + +const int32_t CBC_QRCoderVersion::VERSION_DECODE_INFO[] = { + 0x07C94, 0x085BC, 0x09A99, 0x0A4D3, 0x0BBF6, 0x0C762, 0x0D847, + 0x0E60D, 0x0F928, 0x10B78, 0x1145D, 0x12A17, 0x13532, 0x149A6, + 0x15683, 0x168C9, 0x177EC, 0x18EC4, 0x191E1, 0x1AFAB, 0x1B08E, + 0x1CC1A, 0x1D33F, 0x1ED75, 0x1F250, 0x209D5, 0x216F0, 0x228BA, + 0x2379F, 0x24B0B, 0x2542E, 0x26A64, 0x27541, 0x28C69}; +CFX_PtrArray* CBC_QRCoderVersion::VERSION = NULL; + +void CBC_QRCoderVersion::Initialize() { + VERSION = new CFX_PtrArray(); +} +void CBC_QRCoderVersion::Finalize() { + for (int32_t i = 0; i < VERSION->GetSize(); i++) { + CBC_QRCoderVersion* v = (CBC_QRCoderVersion*)(VERSION->GetAt(i)); + delete v; + } + delete VERSION; +} +CBC_QRCoderVersion::CBC_QRCoderVersion(int32_t versionNumber, + CBC_QRCoderECBlocks* ecBlocks1, + CBC_QRCoderECBlocks* ecBlocks2, + CBC_QRCoderECBlocks* ecBlocks3, + CBC_QRCoderECBlocks* ecBlocks4) { + m_versionNumber = versionNumber; + m_ecBlocks.Add(ecBlocks1); + m_ecBlocks.Add(ecBlocks2); + m_ecBlocks.Add(ecBlocks3); + m_ecBlocks.Add(ecBlocks4); + int32_t total = 0; + int32_t ecCodeWords = ecBlocks1->GetECCodeWordsPerBlock(); + CFX_PtrArray* ecbArray = ecBlocks1->GetECBlocks(); + for (int32_t i = 0; i < ecbArray->GetSize(); i++) { + CBC_QRCoderECB* ecBlock = (CBC_QRCoderECB*)((*ecbArray)[i]); + total += ecBlock->GetCount() * (ecBlock->GetDataCodeWords() + ecCodeWords); + } + m_totalCodeWords = total; + switch (versionNumber) { + case 1: + break; + case 2: + m_alignmentPatternCenters.Add(6); + m_alignmentPatternCenters.Add(18); + break; + case 3: + m_alignmentPatternCenters.Add(6); + m_alignmentPatternCenters.Add(22); + break; + case 4: + m_alignmentPatternCenters.Add(6); + m_alignmentPatternCenters.Add(26); + break; + case 5: + m_alignmentPatternCenters.Add(6); + m_alignmentPatternCenters.Add(30); + break; + case 6: + m_alignmentPatternCenters.Add(6); + m_alignmentPatternCenters.Add(34); + break; + case 7: + m_alignmentPatternCenters.Add(6); + m_alignmentPatternCenters.Add(22); + m_alignmentPatternCenters.Add(38); + break; + case 8: + m_alignmentPatternCenters.Add(6); + m_alignmentPatternCenters.Add(24); + m_alignmentPatternCenters.Add(42); + break; + case 9: + m_alignmentPatternCenters.Add(6); + m_alignmentPatternCenters.Add(26); + m_alignmentPatternCenters.Add(46); + break; + case 10: + m_alignmentPatternCenters.Add(6); + m_alignmentPatternCenters.Add(28); + m_alignmentPatternCenters.Add(50); + break; + case 11: + m_alignmentPatternCenters.Add(6); + m_alignmentPatternCenters.Add(30); + m_alignmentPatternCenters.Add(54); + break; + case 12: + m_alignmentPatternCenters.Add(6); + m_alignmentPatternCenters.Add(32); + m_alignmentPatternCenters.Add(58); + break; + case 13: + m_alignmentPatternCenters.Add(6); + m_alignmentPatternCenters.Add(34); + m_alignmentPatternCenters.Add(62); + break; + case 14: + m_alignmentPatternCenters.Add(6); + m_alignmentPatternCenters.Add(26); + m_alignmentPatternCenters.Add(46); + m_alignmentPatternCenters.Add(66); + break; + case 15: + m_alignmentPatternCenters.Add(6); + m_alignmentPatternCenters.Add(26); + m_alignmentPatternCenters.Add(48); + m_alignmentPatternCenters.Add(70); + break; + case 16: + m_alignmentPatternCenters.Add(6); + m_alignmentPatternCenters.Add(26); + m_alignmentPatternCenters.Add(50); + m_alignmentPatternCenters.Add(74); + break; + case 17: + m_alignmentPatternCenters.Add(6); + m_alignmentPatternCenters.Add(30); + m_alignmentPatternCenters.Add(54); + m_alignmentPatternCenters.Add(78); + break; + case 18: + m_alignmentPatternCenters.Add(6); + m_alignmentPatternCenters.Add(30); + m_alignmentPatternCenters.Add(56); + m_alignmentPatternCenters.Add(82); + break; + case 19: + m_alignmentPatternCenters.Add(6); + m_alignmentPatternCenters.Add(30); + m_alignmentPatternCenters.Add(58); + m_alignmentPatternCenters.Add(86); + break; + case 20: + m_alignmentPatternCenters.Add(6); + m_alignmentPatternCenters.Add(34); + m_alignmentPatternCenters.Add(62); + m_alignmentPatternCenters.Add(90); + break; + case 21: + m_alignmentPatternCenters.Add(6); + m_alignmentPatternCenters.Add(28); + m_alignmentPatternCenters.Add(50); + m_alignmentPatternCenters.Add(72); + m_alignmentPatternCenters.Add(94); + break; + case 22: + m_alignmentPatternCenters.Add(6); + m_alignmentPatternCenters.Add(26); + m_alignmentPatternCenters.Add(50); + m_alignmentPatternCenters.Add(74); + m_alignmentPatternCenters.Add(98); + break; + case 23: + m_alignmentPatternCenters.Add(6); + m_alignmentPatternCenters.Add(30); + m_alignmentPatternCenters.Add(54); + m_alignmentPatternCenters.Add(74); + m_alignmentPatternCenters.Add(102); + break; + case 24: + m_alignmentPatternCenters.Add(6); + m_alignmentPatternCenters.Add(28); + m_alignmentPatternCenters.Add(54); + m_alignmentPatternCenters.Add(80); + m_alignmentPatternCenters.Add(106); + break; + case 25: + m_alignmentPatternCenters.Add(6); + m_alignmentPatternCenters.Add(32); + m_alignmentPatternCenters.Add(58); + m_alignmentPatternCenters.Add(84); + m_alignmentPatternCenters.Add(110); + break; + case 26: + m_alignmentPatternCenters.Add(6); + m_alignmentPatternCenters.Add(30); + m_alignmentPatternCenters.Add(58); + m_alignmentPatternCenters.Add(86); + m_alignmentPatternCenters.Add(114); + break; + case 27: + m_alignmentPatternCenters.Add(6); + m_alignmentPatternCenters.Add(34); + m_alignmentPatternCenters.Add(62); + m_alignmentPatternCenters.Add(90); + m_alignmentPatternCenters.Add(118); + break; + case 28: + m_alignmentPatternCenters.Add(6); + m_alignmentPatternCenters.Add(26); + m_alignmentPatternCenters.Add(50); + m_alignmentPatternCenters.Add(74); + m_alignmentPatternCenters.Add(98); + m_alignmentPatternCenters.Add(122); + break; + case 29: + m_alignmentPatternCenters.Add(6); + m_alignmentPatternCenters.Add(30); + m_alignmentPatternCenters.Add(54); + m_alignmentPatternCenters.Add(78); + m_alignmentPatternCenters.Add(102); + m_alignmentPatternCenters.Add(126); + break; + case 30: + m_alignmentPatternCenters.Add(6); + m_alignmentPatternCenters.Add(26); + m_alignmentPatternCenters.Add(52); + m_alignmentPatternCenters.Add(78); + m_alignmentPatternCenters.Add(104); + m_alignmentPatternCenters.Add(130); + break; + case 31: + m_alignmentPatternCenters.Add(6); + m_alignmentPatternCenters.Add(30); + m_alignmentPatternCenters.Add(56); + m_alignmentPatternCenters.Add(82); + m_alignmentPatternCenters.Add(108); + m_alignmentPatternCenters.Add(134); + break; + case 32: + m_alignmentPatternCenters.Add(6); + m_alignmentPatternCenters.Add(34); + m_alignmentPatternCenters.Add(60); + m_alignmentPatternCenters.Add(86); + m_alignmentPatternCenters.Add(112); + m_alignmentPatternCenters.Add(138); + break; + case 33: + m_alignmentPatternCenters.Add(6); + m_alignmentPatternCenters.Add(30); + m_alignmentPatternCenters.Add(58); + m_alignmentPatternCenters.Add(86); + m_alignmentPatternCenters.Add(114); + m_alignmentPatternCenters.Add(142); + break; + case 34: + m_alignmentPatternCenters.Add(6); + m_alignmentPatternCenters.Add(34); + m_alignmentPatternCenters.Add(62); + m_alignmentPatternCenters.Add(90); + m_alignmentPatternCenters.Add(118); + m_alignmentPatternCenters.Add(146); + break; + case 35: + m_alignmentPatternCenters.Add(6); + m_alignmentPatternCenters.Add(30); + m_alignmentPatternCenters.Add(54); + m_alignmentPatternCenters.Add(78); + m_alignmentPatternCenters.Add(102); + m_alignmentPatternCenters.Add(126); + m_alignmentPatternCenters.Add(150); + break; + case 36: + m_alignmentPatternCenters.Add(6); + m_alignmentPatternCenters.Add(24); + m_alignmentPatternCenters.Add(50); + m_alignmentPatternCenters.Add(76); + m_alignmentPatternCenters.Add(102); + m_alignmentPatternCenters.Add(128); + m_alignmentPatternCenters.Add(154); + break; + case 37: + m_alignmentPatternCenters.Add(6); + m_alignmentPatternCenters.Add(28); + m_alignmentPatternCenters.Add(54); + m_alignmentPatternCenters.Add(80); + m_alignmentPatternCenters.Add(106); + m_alignmentPatternCenters.Add(132); + m_alignmentPatternCenters.Add(158); + break; + case 38: + m_alignmentPatternCenters.Add(6); + m_alignmentPatternCenters.Add(32); + m_alignmentPatternCenters.Add(58); + m_alignmentPatternCenters.Add(84); + m_alignmentPatternCenters.Add(110); + m_alignmentPatternCenters.Add(136); + m_alignmentPatternCenters.Add(162); + break; + case 39: + m_alignmentPatternCenters.Add(6); + m_alignmentPatternCenters.Add(26); + m_alignmentPatternCenters.Add(54); + m_alignmentPatternCenters.Add(82); + m_alignmentPatternCenters.Add(110); + m_alignmentPatternCenters.Add(138); + m_alignmentPatternCenters.Add(166); + break; + case 40: + m_alignmentPatternCenters.Add(6); + m_alignmentPatternCenters.Add(30); + m_alignmentPatternCenters.Add(58); + m_alignmentPatternCenters.Add(86); + m_alignmentPatternCenters.Add(114); + m_alignmentPatternCenters.Add(142); + m_alignmentPatternCenters.Add(170); + break; + } +} +CBC_QRCoderVersion::~CBC_QRCoderVersion() { + if (m_ecBlocks.GetSize() != 0) { + int32_t itBeg = 0; + int32_t itEnd = m_ecBlocks.GetSize(); + while (itBeg != itEnd) { + delete ((CBC_QRCoderECBlocks*)(m_ecBlocks[itBeg])); + itBeg++; + } + } +} +int32_t CBC_QRCoderVersion::GetVersionNumber() { + return m_versionNumber; +} +CFX_Int32Array* CBC_QRCoderVersion::GetAlignmentPatternCenters() { + return &m_alignmentPatternCenters; +} +int32_t CBC_QRCoderVersion::GetTotalCodeWords() { + return m_totalCodeWords; +} +int32_t CBC_QRCoderVersion::GetDimensionForVersion() { + return 17 + 4 * m_versionNumber; +} +CBC_QRCoderECBlocks* CBC_QRCoderVersion::GetECBlocksForLevel( + CBC_QRCoderErrorCorrectionLevel* ecLevel) { + return (CBC_QRCoderECBlocks*)m_ecBlocks[ecLevel->Ordinal()]; +} +CBC_QRCoderVersion* CBC_QRCoderVersion::GetProvisionalVersionForDimension( + int32_t dimension, + int32_t& e) { + if ((dimension % 4) != 1) { + e = BCExceptionRead; + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + } + CBC_QRCoderVersion* qcv = GetVersionForNumber((dimension - 17) >> 2, e); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + return qcv; +} +CBC_QRCoderVersion* CBC_QRCoderVersion::DecodeVersionInformation( + int32_t versionBits, + int32_t& e) { + int32_t bestDifference = FXSYS_IntMax; + int32_t bestVersion = 0; + for (int32_t i = 0; i < 34; i++) { + int32_t targetVersion = VERSION_DECODE_INFO[i]; + if (targetVersion == versionBits) { + CBC_QRCoderVersion* qcv = GetVersionForNumber(i + 7, e); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + return qcv; + } + int32_t bitsDifference = CBC_QRCoderFormatInformation::NumBitsDiffering( + versionBits, targetVersion); + if (bitsDifference < bestDifference) { + bestVersion = i + 7; + bestDifference = bitsDifference; + } + } + if (bestDifference <= 3) { + CBC_QRCoderVersion* qcv = GetVersionForNumber(bestVersion, e); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + return qcv; + } + return NULL; +} +CBC_CommonBitMatrix* CBC_QRCoderVersion::BuildFunctionPattern(int32_t& e) { + int32_t dimension = GetDimensionForVersion(); + CBC_CommonBitMatrix* bitMatrix = new CBC_CommonBitMatrix(); + bitMatrix->Init(dimension); + bitMatrix->SetRegion(0, 0, 9, 9, e); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + bitMatrix->SetRegion(dimension - 8, 0, 8, 9, e); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + bitMatrix->SetRegion(0, dimension - 8, 9, 8, e); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + int32_t max = m_alignmentPatternCenters.GetSize(); + for (int32_t x = 0; x < max; x++) { + int32_t i = m_alignmentPatternCenters[x] - 2; + for (int32_t y = 0; y < max; y++) { + if ((x == 0 && (y == 0 || y == max - 1)) || (x == max - 1 && y == 0)) { + continue; + } + bitMatrix->SetRegion(m_alignmentPatternCenters[y] - 2, i, 5, 5, e); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + } + } + bitMatrix->SetRegion(6, 9, 1, dimension - 17, e); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + bitMatrix->SetRegion(9, 6, dimension - 17, 1, e); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + if (m_versionNumber > 6) { + bitMatrix->SetRegion(dimension - 11, 0, 3, 6, e); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + bitMatrix->SetRegion(0, dimension - 11, 6, 3, e); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + } + return bitMatrix; +} +CBC_QRCoderVersion* CBC_QRCoderVersion::GetVersionForNumber( + int32_t versionNumber, + int32_t& e) { + if (VERSION->GetSize() == 0) { + VERSION->Add(new CBC_QRCoderVersion( + 1, new CBC_QRCoderECBlocks(7, new CBC_QRCoderECB(1, 19)), + new CBC_QRCoderECBlocks(10, new CBC_QRCoderECB(1, 16)), + new CBC_QRCoderECBlocks(13, new CBC_QRCoderECB(1, 13)), + new CBC_QRCoderECBlocks(17, new CBC_QRCoderECB(1, 9)))); + VERSION->Add(new CBC_QRCoderVersion( + 2, new CBC_QRCoderECBlocks(10, new CBC_QRCoderECB(1, 34)), + new CBC_QRCoderECBlocks(16, new CBC_QRCoderECB(1, 28)), + new CBC_QRCoderECBlocks(22, new CBC_QRCoderECB(1, 22)), + new CBC_QRCoderECBlocks(28, new CBC_QRCoderECB(1, 16)))); + VERSION->Add(new CBC_QRCoderVersion( + 3, new CBC_QRCoderECBlocks(15, new CBC_QRCoderECB(1, 55)), + new CBC_QRCoderECBlocks(26, new CBC_QRCoderECB(1, 44)), + new CBC_QRCoderECBlocks(18, new CBC_QRCoderECB(2, 17)), + new CBC_QRCoderECBlocks(22, new CBC_QRCoderECB(2, 13)))); + VERSION->Add(new CBC_QRCoderVersion( + 4, new CBC_QRCoderECBlocks(20, new CBC_QRCoderECB(1, 80)), + new CBC_QRCoderECBlocks(18, new CBC_QRCoderECB(2, 32)), + new CBC_QRCoderECBlocks(26, new CBC_QRCoderECB(2, 24)), + new CBC_QRCoderECBlocks(16, new CBC_QRCoderECB(4, 9)))); + VERSION->Add(new CBC_QRCoderVersion( + 5, new CBC_QRCoderECBlocks(26, new CBC_QRCoderECB(1, 108)), + new CBC_QRCoderECBlocks(24, new CBC_QRCoderECB(2, 43)), + new CBC_QRCoderECBlocks(18, new CBC_QRCoderECB(2, 15), + new CBC_QRCoderECB(2, 16)), + new CBC_QRCoderECBlocks(22, new CBC_QRCoderECB(2, 11), + new CBC_QRCoderECB(2, 12)))); + VERSION->Add(new CBC_QRCoderVersion( + 6, new CBC_QRCoderECBlocks(18, new CBC_QRCoderECB(2, 68)), + new CBC_QRCoderECBlocks(16, new CBC_QRCoderECB(4, 27)), + new CBC_QRCoderECBlocks(24, new CBC_QRCoderECB(4, 19)), + new CBC_QRCoderECBlocks(28, new CBC_QRCoderECB(4, 15)))); + VERSION->Add(new CBC_QRCoderVersion( + 7, new CBC_QRCoderECBlocks(20, new CBC_QRCoderECB(2, 78)), + new CBC_QRCoderECBlocks(18, new CBC_QRCoderECB(4, 31)), + new CBC_QRCoderECBlocks(18, new CBC_QRCoderECB(2, 14), + new CBC_QRCoderECB(4, 15)), + new CBC_QRCoderECBlocks(26, new CBC_QRCoderECB(4, 13), + new CBC_QRCoderECB(1, 14)))); + VERSION->Add(new CBC_QRCoderVersion( + 8, new CBC_QRCoderECBlocks(24, new CBC_QRCoderECB(2, 97)), + new CBC_QRCoderECBlocks(22, new CBC_QRCoderECB(2, 38), + new CBC_QRCoderECB(2, 39)), + new CBC_QRCoderECBlocks(22, new CBC_QRCoderECB(4, 18), + new CBC_QRCoderECB(2, 19)), + new CBC_QRCoderECBlocks(26, new CBC_QRCoderECB(4, 14), + new CBC_QRCoderECB(2, 15)))); + VERSION->Add(new CBC_QRCoderVersion( + 9, new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(2, 116)), + new CBC_QRCoderECBlocks(22, new CBC_QRCoderECB(3, 36), + new CBC_QRCoderECB(2, 37)), + new CBC_QRCoderECBlocks(20, new CBC_QRCoderECB(4, 16), + new CBC_QRCoderECB(4, 17)), + new CBC_QRCoderECBlocks(24, new CBC_QRCoderECB(4, 12), + new CBC_QRCoderECB(4, 13)))); + VERSION->Add(new CBC_QRCoderVersion( + 10, new CBC_QRCoderECBlocks(18, new CBC_QRCoderECB(2, 68), + new CBC_QRCoderECB(2, 69)), + new CBC_QRCoderECBlocks(26, new CBC_QRCoderECB(4, 43), + new CBC_QRCoderECB(1, 44)), + new CBC_QRCoderECBlocks(24, new CBC_QRCoderECB(6, 19), + new CBC_QRCoderECB(2, 20)), + new CBC_QRCoderECBlocks(28, new CBC_QRCoderECB(6, 15), + new CBC_QRCoderECB(2, 16)))); + VERSION->Add(new CBC_QRCoderVersion( + 11, new CBC_QRCoderECBlocks(20, new CBC_QRCoderECB(4, 81)), + new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(1, 50), + new CBC_QRCoderECB(4, 51)), + new CBC_QRCoderECBlocks(28, new CBC_QRCoderECB(4, 22), + new CBC_QRCoderECB(4, 23)), + new CBC_QRCoderECBlocks(24, new CBC_QRCoderECB(3, 12), + new CBC_QRCoderECB(8, 13)))); + VERSION->Add(new CBC_QRCoderVersion( + 12, new CBC_QRCoderECBlocks(24, new CBC_QRCoderECB(2, 92), + new CBC_QRCoderECB(2, 93)), + new CBC_QRCoderECBlocks(22, new CBC_QRCoderECB(6, 36), + new CBC_QRCoderECB(2, 37)), + new CBC_QRCoderECBlocks(26, new CBC_QRCoderECB(4, 20), + new CBC_QRCoderECB(6, 21)), + new CBC_QRCoderECBlocks(28, new CBC_QRCoderECB(7, 14), + new CBC_QRCoderECB(4, 15)))); + VERSION->Add(new CBC_QRCoderVersion( + 13, new CBC_QRCoderECBlocks(26, new CBC_QRCoderECB(4, 107)), + new CBC_QRCoderECBlocks(22, new CBC_QRCoderECB(8, 37), + new CBC_QRCoderECB(1, 38)), + new CBC_QRCoderECBlocks(24, new CBC_QRCoderECB(8, 20), + new CBC_QRCoderECB(4, 21)), + new CBC_QRCoderECBlocks(22, new CBC_QRCoderECB(12, 11), + new CBC_QRCoderECB(4, 12)))); + VERSION->Add(new CBC_QRCoderVersion( + 14, new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(3, 115), + new CBC_QRCoderECB(1, 116)), + new CBC_QRCoderECBlocks(24, new CBC_QRCoderECB(4, 40), + new CBC_QRCoderECB(5, 41)), + new CBC_QRCoderECBlocks(20, new CBC_QRCoderECB(11, 16), + new CBC_QRCoderECB(5, 17)), + new CBC_QRCoderECBlocks(24, new CBC_QRCoderECB(11, 12), + new CBC_QRCoderECB(5, 13)))); + VERSION->Add(new CBC_QRCoderVersion( + 15, new CBC_QRCoderECBlocks(22, new CBC_QRCoderECB(5, 87), + new CBC_QRCoderECB(1, 88)), + new CBC_QRCoderECBlocks(24, new CBC_QRCoderECB(5, 41), + new CBC_QRCoderECB(5, 42)), + new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(5, 24), + new CBC_QRCoderECB(7, 25)), + new CBC_QRCoderECBlocks(24, new CBC_QRCoderECB(11, 12), + new CBC_QRCoderECB(7, 13)))); + VERSION->Add(new CBC_QRCoderVersion( + 16, new CBC_QRCoderECBlocks(24, new CBC_QRCoderECB(5, 98), + new CBC_QRCoderECB(1, 99)), + new CBC_QRCoderECBlocks(28, new CBC_QRCoderECB(7, 45), + new CBC_QRCoderECB(3, 46)), + new CBC_QRCoderECBlocks(24, new CBC_QRCoderECB(15, 19), + new CBC_QRCoderECB(2, 20)), + new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(3, 15), + new CBC_QRCoderECB(13, 16)))); + VERSION->Add(new CBC_QRCoderVersion( + 17, new CBC_QRCoderECBlocks(28, new CBC_QRCoderECB(1, 107), + new CBC_QRCoderECB(5, 108)), + new CBC_QRCoderECBlocks(28, new CBC_QRCoderECB(10, 46), + new CBC_QRCoderECB(1, 47)), + new CBC_QRCoderECBlocks(28, new CBC_QRCoderECB(1, 22), + new CBC_QRCoderECB(15, 23)), + new CBC_QRCoderECBlocks(28, new CBC_QRCoderECB(2, 14), + new CBC_QRCoderECB(17, 15)))); + VERSION->Add(new CBC_QRCoderVersion( + 18, new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(5, 120), + new CBC_QRCoderECB(1, 121)), + new CBC_QRCoderECBlocks(26, new CBC_QRCoderECB(9, 43), + new CBC_QRCoderECB(4, 44)), + new CBC_QRCoderECBlocks(28, new CBC_QRCoderECB(17, 22), + new CBC_QRCoderECB(1, 23)), + new CBC_QRCoderECBlocks(28, new CBC_QRCoderECB(2, 14), + new CBC_QRCoderECB(19, 15)))); + VERSION->Add(new CBC_QRCoderVersion( + 19, new CBC_QRCoderECBlocks(28, new CBC_QRCoderECB(3, 113), + new CBC_QRCoderECB(4, 114)), + new CBC_QRCoderECBlocks(26, new CBC_QRCoderECB(3, 44), + new CBC_QRCoderECB(11, 45)), + new CBC_QRCoderECBlocks(26, new CBC_QRCoderECB(17, 21), + new CBC_QRCoderECB(4, 22)), + new CBC_QRCoderECBlocks(26, new CBC_QRCoderECB(9, 13), + new CBC_QRCoderECB(16, 14)))); + VERSION->Add(new CBC_QRCoderVersion( + 20, new CBC_QRCoderECBlocks(28, new CBC_QRCoderECB(3, 107), + new CBC_QRCoderECB(5, 108)), + new CBC_QRCoderECBlocks(26, new CBC_QRCoderECB(3, 41), + new CBC_QRCoderECB(13, 42)), + new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(15, 24), + new CBC_QRCoderECB(5, 25)), + new CBC_QRCoderECBlocks(28, new CBC_QRCoderECB(15, 15), + new CBC_QRCoderECB(10, 16)))); + VERSION->Add(new CBC_QRCoderVersion( + 21, new CBC_QRCoderECBlocks(28, new CBC_QRCoderECB(4, 116), + new CBC_QRCoderECB(4, 117)), + new CBC_QRCoderECBlocks(26, new CBC_QRCoderECB(17, 42)), + new CBC_QRCoderECBlocks(28, new CBC_QRCoderECB(17, 22), + new CBC_QRCoderECB(6, 23)), + new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(19, 16), + new CBC_QRCoderECB(6, 17)))); + VERSION->Add(new CBC_QRCoderVersion( + 22, new CBC_QRCoderECBlocks(28, new CBC_QRCoderECB(2, 111), + new CBC_QRCoderECB(7, 112)), + new CBC_QRCoderECBlocks(28, new CBC_QRCoderECB(17, 46)), + new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(7, 24), + new CBC_QRCoderECB(16, 25)), + new CBC_QRCoderECBlocks(24, new CBC_QRCoderECB(34, 13)))); + VERSION->Add(new CBC_QRCoderVersion( + 23, new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(4, 121), + new CBC_QRCoderECB(5, 122)), + new CBC_QRCoderECBlocks(28, new CBC_QRCoderECB(4, 47), + new CBC_QRCoderECB(14, 48)), + new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(11, 24), + new CBC_QRCoderECB(14, 25)), + new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(16, 15), + new CBC_QRCoderECB(14, 16)))); + VERSION->Add(new CBC_QRCoderVersion( + 24, new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(6, 117), + new CBC_QRCoderECB(4, 118)), + new CBC_QRCoderECBlocks(28, new CBC_QRCoderECB(6, 45), + new CBC_QRCoderECB(14, 46)), + new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(11, 24), + new CBC_QRCoderECB(16, 25)), + new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(30, 16), + new CBC_QRCoderECB(2, 17)))); + VERSION->Add(new CBC_QRCoderVersion( + 25, new CBC_QRCoderECBlocks(26, new CBC_QRCoderECB(8, 106), + new CBC_QRCoderECB(4, 107)), + new CBC_QRCoderECBlocks(28, new CBC_QRCoderECB(8, 47), + new CBC_QRCoderECB(13, 48)), + new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(7, 24), + new CBC_QRCoderECB(22, 25)), + new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(22, 15), + new CBC_QRCoderECB(13, 16)))); + VERSION->Add(new CBC_QRCoderVersion( + 26, new CBC_QRCoderECBlocks(28, new CBC_QRCoderECB(10, 114), + new CBC_QRCoderECB(2, 115)), + new CBC_QRCoderECBlocks(28, new CBC_QRCoderECB(19, 46), + new CBC_QRCoderECB(4, 47)), + new CBC_QRCoderECBlocks(28, new CBC_QRCoderECB(28, 22), + new CBC_QRCoderECB(6, 23)), + new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(33, 16), + new CBC_QRCoderECB(4, 17)))); + VERSION->Add(new CBC_QRCoderVersion( + 27, new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(8, 122), + new CBC_QRCoderECB(4, 123)), + new CBC_QRCoderECBlocks(28, new CBC_QRCoderECB(22, 45), + new CBC_QRCoderECB(3, 46)), + new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(8, 23), + new CBC_QRCoderECB(26, 24)), + new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(12, 15), + new CBC_QRCoderECB(28, 16)))); + VERSION->Add(new CBC_QRCoderVersion( + 28, new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(3, 117), + new CBC_QRCoderECB(10, 118)), + new CBC_QRCoderECBlocks(28, new CBC_QRCoderECB(3, 45), + new CBC_QRCoderECB(23, 46)), + new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(4, 24), + new CBC_QRCoderECB(31, 25)), + new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(11, 15), + new CBC_QRCoderECB(31, 16)))); + VERSION->Add(new CBC_QRCoderVersion( + 29, new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(7, 116), + new CBC_QRCoderECB(7, 117)), + new CBC_QRCoderECBlocks(28, new CBC_QRCoderECB(21, 45), + new CBC_QRCoderECB(7, 46)), + new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(1, 23), + new CBC_QRCoderECB(37, 24)), + new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(19, 15), + new CBC_QRCoderECB(26, 16)))); + VERSION->Add(new CBC_QRCoderVersion( + 30, new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(5, 115), + new CBC_QRCoderECB(10, 116)), + new CBC_QRCoderECBlocks(28, new CBC_QRCoderECB(19, 47), + new CBC_QRCoderECB(10, 48)), + new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(15, 24), + new CBC_QRCoderECB(25, 25)), + new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(23, 15), + new CBC_QRCoderECB(25, 16)))); + VERSION->Add(new CBC_QRCoderVersion( + 31, new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(13, 115), + new CBC_QRCoderECB(3, 116)), + new CBC_QRCoderECBlocks(28, new CBC_QRCoderECB(2, 46), + new CBC_QRCoderECB(29, 47)), + new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(42, 24), + new CBC_QRCoderECB(1, 25)), + new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(23, 15), + new CBC_QRCoderECB(28, 16)))); + VERSION->Add(new CBC_QRCoderVersion( + 32, new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(17, 115)), + new CBC_QRCoderECBlocks(28, new CBC_QRCoderECB(10, 46), + new CBC_QRCoderECB(23, 47)), + new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(10, 24), + new CBC_QRCoderECB(35, 25)), + new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(19, 15), + new CBC_QRCoderECB(35, 16)))); + VERSION->Add(new CBC_QRCoderVersion( + 33, new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(17, 115), + new CBC_QRCoderECB(1, 116)), + new CBC_QRCoderECBlocks(28, new CBC_QRCoderECB(14, 46), + new CBC_QRCoderECB(21, 47)), + new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(29, 24), + new CBC_QRCoderECB(19, 25)), + new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(11, 15), + new CBC_QRCoderECB(46, 16)))); + VERSION->Add(new CBC_QRCoderVersion( + 34, new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(13, 115), + new CBC_QRCoderECB(6, 116)), + new CBC_QRCoderECBlocks(28, new CBC_QRCoderECB(14, 46), + new CBC_QRCoderECB(23, 47)), + new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(44, 24), + new CBC_QRCoderECB(7, 25)), + new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(59, 16), + new CBC_QRCoderECB(1, 17)))); + VERSION->Add(new CBC_QRCoderVersion( + 35, new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(12, 121), + new CBC_QRCoderECB(7, 122)), + new CBC_QRCoderECBlocks(28, new CBC_QRCoderECB(12, 47), + new CBC_QRCoderECB(26, 48)), + new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(39, 24), + new CBC_QRCoderECB(14, 25)), + new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(22, 15), + new CBC_QRCoderECB(41, 16)))); + VERSION->Add(new CBC_QRCoderVersion( + 36, new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(6, 121), + new CBC_QRCoderECB(14, 122)), + new CBC_QRCoderECBlocks(28, new CBC_QRCoderECB(6, 47), + new CBC_QRCoderECB(34, 48)), + new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(46, 24), + new CBC_QRCoderECB(10, 25)), + new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(2, 15), + new CBC_QRCoderECB(64, 16)))); + VERSION->Add(new CBC_QRCoderVersion( + 37, new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(17, 122), + new CBC_QRCoderECB(4, 123)), + new CBC_QRCoderECBlocks(28, new CBC_QRCoderECB(29, 46), + new CBC_QRCoderECB(14, 47)), + new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(49, 24), + new CBC_QRCoderECB(10, 25)), + new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(24, 15), + new CBC_QRCoderECB(46, 16)))); + VERSION->Add(new CBC_QRCoderVersion( + 38, new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(4, 122), + new CBC_QRCoderECB(18, 123)), + new CBC_QRCoderECBlocks(28, new CBC_QRCoderECB(13, 46), + new CBC_QRCoderECB(32, 47)), + new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(48, 24), + new CBC_QRCoderECB(14, 25)), + new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(42, 15), + new CBC_QRCoderECB(32, 16)))); + VERSION->Add(new CBC_QRCoderVersion( + 39, new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(20, 117), + new CBC_QRCoderECB(4, 118)), + new CBC_QRCoderECBlocks(28, new CBC_QRCoderECB(40, 47), + new CBC_QRCoderECB(7, 48)), + new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(43, 24), + new CBC_QRCoderECB(22, 25)), + new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(10, 15), + new CBC_QRCoderECB(67, 16)))); + VERSION->Add(new CBC_QRCoderVersion( + 40, new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(19, 118), + new CBC_QRCoderECB(6, 119)), + new CBC_QRCoderECBlocks(28, new CBC_QRCoderECB(18, 47), + new CBC_QRCoderECB(31, 48)), + new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(34, 24), + new CBC_QRCoderECB(34, 25)), + new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(20, 15), + new CBC_QRCoderECB(61, 16)))); + } + if (versionNumber < 1 || versionNumber > 40) { + e = BCExceptionIllegalArgument; + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + } + return (CBC_QRCoderVersion*)(*VERSION)[versionNumber - 1]; +} +void CBC_QRCoderVersion::Destroy() { + int32_t i; + for (i = 0; i < VERSION->GetSize(); i++) { + delete ((CBC_QRCoderVersion*)(*VERSION)[i]); + } +} diff --git a/xfa/fxbarcode/qrcode/BC_QRCoderVersion.h b/xfa/fxbarcode/qrcode/BC_QRCoderVersion.h new file mode 100644 index 0000000000..dd2b0c6be8 --- /dev/null +++ b/xfa/fxbarcode/qrcode/BC_QRCoderVersion.h @@ -0,0 +1,54 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef XFA_FXBARCODE_QRCODE_BC_QRCODERVERSION_H_ +#define XFA_FXBARCODE_QRCODE_BC_QRCODERVERSION_H_ + +#include "core/include/fxcrt/fx_basic.h" + +class CBC_QRCoderECBlocks; +class CBC_CommonBitMatrix; +class CBC_QRCoderErrorCorrectionLevel; + +class CBC_QRCoderVersion { + private: + static const int32_t VERSION_DECODE_INFO[34]; + static CFX_PtrArray* VERSION; + int32_t m_versionNumber; + int32_t m_totalCodeWords; + CFX_Int32Array m_alignmentPatternCenters; + CFX_PtrArray m_ecBlocks; + + CBC_QRCoderVersion(); + CBC_QRCoderVersion(int32_t versionNumber, + CBC_QRCoderECBlocks* ecBlocks1, + CBC_QRCoderECBlocks* ecBlocks2, + CBC_QRCoderECBlocks* ecBlocks3, + CBC_QRCoderECBlocks* ecBlocks4); + + public: + virtual ~CBC_QRCoderVersion(); + static void Initialize(); + static void Finalize(); + + int32_t GetVersionNumber(); + int32_t GetTotalCodeWords(); + int32_t GetDimensionForVersion(); + CBC_CommonBitMatrix* BuildFunctionPattern(int32_t& e); + CFX_Int32Array* GetAlignmentPatternCenters(); + CBC_QRCoderECBlocks* GetECBlocksForLevel( + CBC_QRCoderErrorCorrectionLevel* ecLevel); + static CBC_QRCoderVersion* GetVersionForNumber(int32_t versionNumber, + int32_t& e); + static CBC_QRCoderVersion* GetProvisionalVersionForDimension( + int32_t dimension, + int32_t& e); + static CBC_QRCoderVersion* DecodeVersionInformation(int32_t versionBits, + int32_t& e); + static void Destroy(); +}; + +#endif // XFA_FXBARCODE_QRCODE_BC_QRCODERVERSION_H_ diff --git a/xfa/fxbarcode/qrcode/BC_QRDataBlock.cpp b/xfa/fxbarcode/qrcode/BC_QRDataBlock.cpp new file mode 100644 index 0000000000..9805ac9af8 --- /dev/null +++ b/xfa/fxbarcode/qrcode/BC_QRDataBlock.cpp @@ -0,0 +1,111 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com +// Original code is licensed as follows: +/* + * Copyright 2007 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "xfa/fxbarcode/qrcode/BC_QRDataBlock.h" + +#include <memory> + +#include "xfa/fxbarcode/qrcode/BC_QRCoderECB.h" +#include "xfa/fxbarcode/qrcode/BC_QRCoderECBlocks.h" +#include "xfa/fxbarcode/qrcode/BC_QRCoderVersion.h" +#include "xfa/fxbarcode/utils.h" + +CBC_QRDataBlock::CBC_QRDataBlock(int32_t numDataCodewords, + CFX_ByteArray* codewords) + : m_numDataCodewords(numDataCodewords), m_codewords(codewords) {} +CBC_QRDataBlock::~CBC_QRDataBlock() { + delete m_codewords; +} +int32_t CBC_QRDataBlock::GetNumDataCodewords() { + return m_numDataCodewords; +} +CFX_ByteArray* CBC_QRDataBlock::GetCodewords() { + return m_codewords; +} +CFX_PtrArray* CBC_QRDataBlock::GetDataBlocks( + CFX_ByteArray* rawCodewords, + CBC_QRCoderVersion* version, + CBC_QRCoderErrorCorrectionLevel* ecLevel, + int32_t& e) { + if (rawCodewords->GetSize() != version->GetTotalCodeWords()) { + e = BCExceptionIllegalArgument; + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + } + CBC_QRCoderECBlocks* ecBlocks = version->GetECBlocksForLevel(ecLevel); + int32_t totalBlocks = 0; + CFX_PtrArray* ecBlockArray = ecBlocks->GetECBlocks(); + int32_t i = 0; + for (i = 0; i < ecBlockArray->GetSize(); i++) { + totalBlocks += ((CBC_QRCoderECB*)(*ecBlockArray)[i])->GetCount(); + } + std::unique_ptr<CFX_PtrArray> result(new CFX_PtrArray()); + result->SetSize(totalBlocks); + int32_t numResultBlocks = 0; + for (int32_t j = 0; j < ecBlockArray->GetSize(); j++) { + CBC_QRCoderECB* ecBlock = (CBC_QRCoderECB*)(*ecBlockArray)[j]; + for (int32_t k = 0; k < ecBlock->GetCount(); k++) { + int32_t numDataCodewords = ecBlock->GetDataCodeWords(); + int32_t numBlockCodewords = + ecBlocks->GetECCodeWordsPerBlock() + numDataCodewords; + CFX_ByteArray* bytearray = new CFX_ByteArray(); + bytearray->SetSize(numBlockCodewords); + (*result)[numResultBlocks++] = + new CBC_QRDataBlock(numDataCodewords, bytearray); + } + } + int32_t shorterBlocksTotalCodewords = + ((CBC_QRDataBlock*)(*result)[0])->m_codewords->GetSize(); + int32_t longerBlocksStartAt = result->GetSize() - 1; + while (longerBlocksStartAt >= 0) { + int32_t numCodewords = ((CBC_QRDataBlock*)(*result)[longerBlocksStartAt]) + ->m_codewords->GetSize(); + if (numCodewords == shorterBlocksTotalCodewords) { + break; + } + longerBlocksStartAt--; + } + longerBlocksStartAt++; + int32_t shorterBlocksNumDataCodewords = + shorterBlocksTotalCodewords - ecBlocks->GetECCodeWordsPerBlock(); + int32_t rawCodewordsOffset = 0; + int32_t x = 0; + for (int32_t k = 0; k < shorterBlocksNumDataCodewords; k++) { + for (x = 0; x < numResultBlocks; x++) { + (*(((CBC_QRDataBlock*)(*result)[x])->m_codewords))[k] = + (*rawCodewords)[rawCodewordsOffset++]; + } + } + for (x = longerBlocksStartAt; x < numResultBlocks; x++) { + (*(((CBC_QRDataBlock*)(*result)[x]) + ->m_codewords))[shorterBlocksNumDataCodewords] = + (*rawCodewords)[rawCodewordsOffset++]; + } + int32_t max = ((CBC_QRDataBlock*)(*result)[0])->m_codewords->GetSize(); + for (i = shorterBlocksNumDataCodewords; i < max; i++) { + for (int32_t y = 0; y < numResultBlocks; y++) { + int32_t iOffset = y < longerBlocksStartAt ? i : i + 1; + (*(((CBC_QRDataBlock*)(*result)[y])->m_codewords))[iOffset] = + (*rawCodewords)[rawCodewordsOffset++]; + } + } + return result.release(); +} diff --git a/xfa/fxbarcode/qrcode/BC_QRDataBlock.h b/xfa/fxbarcode/qrcode/BC_QRDataBlock.h new file mode 100644 index 0000000000..8e11ab845c --- /dev/null +++ b/xfa/fxbarcode/qrcode/BC_QRDataBlock.h @@ -0,0 +1,30 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef XFA_FXBARCODE_QRCODE_BC_QRDATABLOCK_H_ +#define XFA_FXBARCODE_QRCODE_BC_QRDATABLOCK_H_ + +#include "core/include/fxcrt/fx_basic.h" + +class CBC_QRCoderVersion; +class CBC_QRCoderErrorCorrectionLevel; +class CBC_QRDataBlock { + private: + int32_t m_numDataCodewords; + CFX_ByteArray* m_codewords; + CBC_QRDataBlock(int32_t numDataCodewords, CFX_ByteArray* codewords); + + public: + virtual ~CBC_QRDataBlock(); + int32_t GetNumDataCodewords(); + CFX_ByteArray* GetCodewords(); + static CFX_PtrArray* GetDataBlocks(CFX_ByteArray* rawCodewords, + CBC_QRCoderVersion* version, + CBC_QRCoderErrorCorrectionLevel* ecLevel, + int32_t& e); +}; + +#endif // XFA_FXBARCODE_QRCODE_BC_QRDATABLOCK_H_ diff --git a/xfa/fxbarcode/qrcode/BC_QRDataMask.cpp b/xfa/fxbarcode/qrcode/BC_QRDataMask.cpp new file mode 100644 index 0000000000..20f94069f4 --- /dev/null +++ b/xfa/fxbarcode/qrcode/BC_QRDataMask.cpp @@ -0,0 +1,118 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com +// Original code is licensed as follows: +/* + * Copyright 2007 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "xfa/fxbarcode/common/BC_CommonBitMatrix.h" +#include "xfa/fxbarcode/qrcode/BC_QRDataMask.h" +#include "xfa/fxbarcode/utils.h" + +static int32_t N_DATA_MASKS = 0; +CFX_PtrArray* CBC_QRDataMask::DATA_MASKS = NULL; + +void CBC_QRDataMask::Initialize() { + DATA_MASKS = new CFX_PtrArray(); + N_DATA_MASKS = BuildDataMasks(); +} +void CBC_QRDataMask::Finalize() { + Destroy(); + delete DATA_MASKS; +} +void CBC_QRDataMask::Destroy() { + int32_t i; + for (i = 0; i < N_DATA_MASKS; i++) { + CBC_QRDataMask* p = (CBC_QRDataMask*)(*DATA_MASKS)[i]; + if (p) { + delete p; + } + } +} +void CBC_QRDataMask::UnmaskBitMatirx(CBC_CommonBitMatrix* bits, + int32_t dimension) { + for (int32_t i = 0; i < dimension; i++) { + for (int32_t j = 0; j < dimension; j++) { + if (IsMasked(i, j)) { + bits->Flip(j, i); + } + } + } +} +CBC_QRDataMask* CBC_QRDataMask::ForReference(int32_t reference, int32_t& e) { + if (reference < 0 || reference > 7) { + e = BCExceptionReferenceMustBeBetween0And7; + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + } + return (CBC_QRDataMask*)(*DATA_MASKS)[reference]; +} +class DataMask000 : public CBC_QRDataMask { + public: + FX_BOOL IsMasked(int32_t x, int32_t y) { return ((x + y) % 2) == 0; } +}; +class DataMask001 : public CBC_QRDataMask { + public: + FX_BOOL IsMasked(int32_t x, int32_t y) { return (x % 2) == 0; } +}; +class DataMask010 : public CBC_QRDataMask { + public: + FX_BOOL IsMasked(int32_t x, int32_t y) { return y % 3 == 0; } +}; +class DataMask011 : public CBC_QRDataMask { + public: + FX_BOOL IsMasked(int32_t x, int32_t y) { return (x + y) % 3 == 0; } +}; +class DataMask100 : public CBC_QRDataMask { + public: + FX_BOOL IsMasked(int32_t x, int32_t y) { + return (((x >> 1) + (y / 3)) % 2) == 0; + } +}; +class DataMask101 : public CBC_QRDataMask { + public: + FX_BOOL IsMasked(int32_t x, int32_t y) { + size_t temp = x * y; + return (temp % 2) + (temp % 3) == 0; + } +}; +class DataMask110 : public CBC_QRDataMask { + public: + FX_BOOL IsMasked(int32_t x, int32_t y) { + size_t temp = x * y; + return (((temp % 2) + (temp % 3)) % 2) == 0; + } +}; +class DataMask111 : public CBC_QRDataMask { + public: + FX_BOOL IsMasked(int32_t x, int32_t y) { + return ((((x + y) % 2) + ((x * y) % 3)) % 2) == 0; + } +}; +int32_t CBC_QRDataMask::BuildDataMasks() { + DATA_MASKS->Add(new DataMask000); + DATA_MASKS->Add(new DataMask001); + DATA_MASKS->Add(new DataMask010); + DATA_MASKS->Add(new DataMask011); + DATA_MASKS->Add(new DataMask100); + DATA_MASKS->Add(new DataMask101); + DATA_MASKS->Add(new DataMask110); + DATA_MASKS->Add(new DataMask111); + return DATA_MASKS->GetSize(); +} +CBC_QRDataMask::CBC_QRDataMask() {} +CBC_QRDataMask::~CBC_QRDataMask() {} diff --git a/xfa/fxbarcode/qrcode/BC_QRDataMask.h b/xfa/fxbarcode/qrcode/BC_QRDataMask.h new file mode 100644 index 0000000000..5893149d3b --- /dev/null +++ b/xfa/fxbarcode/qrcode/BC_QRDataMask.h @@ -0,0 +1,28 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef XFA_FXBARCODE_QRCODE_BC_QRDATAMASK_H_ +#define XFA_FXBARCODE_QRCODE_BC_QRDATAMASK_H_ + +#include "core/include/fxcrt/fx_basic.h" + +class CBC_CommonBitMatrix; + +class CBC_QRDataMask { + public: + static CFX_PtrArray* DATA_MASKS; + CBC_QRDataMask(); + virtual ~CBC_QRDataMask(); + static void Initialize(); + static void Finalize(); + virtual FX_BOOL IsMasked(int32_t i, int32_t j) = 0; + void UnmaskBitMatirx(CBC_CommonBitMatrix* bits, int32_t dimension); + static CBC_QRDataMask* ForReference(int32_t reference, int32_t& e); + static int32_t BuildDataMasks(); + static void Destroy(); +}; + +#endif // XFA_FXBARCODE_QRCODE_BC_QRDATAMASK_H_ diff --git a/xfa/fxbarcode/qrcode/BC_QRDecodedBitStreamParser.cpp b/xfa/fxbarcode/qrcode/BC_QRDecodedBitStreamParser.cpp new file mode 100644 index 0000000000..8919c3a9a1 --- /dev/null +++ b/xfa/fxbarcode/qrcode/BC_QRDecodedBitStreamParser.cpp @@ -0,0 +1,273 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com +// Original code is licensed as follows: +/* + * Copyright 2007 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "xfa/fxbarcode/BC_UtilCodingConvert.h" +#include "xfa/fxbarcode/common/BC_CommonBitSource.h" +#include "xfa/fxbarcode/common/BC_CommonCharacterSetECI.h" +#include "xfa/fxbarcode/common/BC_CommonDecoderResult.h" +#include "xfa/fxbarcode/common/BC_CommonECI.h" +#include "xfa/fxbarcode/qrcode/BC_QRCoderMode.h" +#include "xfa/fxbarcode/qrcode/BC_QRDecodedBitStreamParser.h" + +const FX_CHAR* CBC_QRDecodedBitStreamParser::UTF_8 = "utf8"; +const FX_CHAR CBC_QRDecodedBitStreamParser::ALPHANUMERIC_CHARS[45] = { + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', + 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', + 'U', 'V', 'W', 'X', 'Y', 'Z', ' ', '$', '%', '*', '+', '-', '.', '/', ':'}; + +CBC_QRDecodedBitStreamParser::CBC_QRDecodedBitStreamParser() {} +CBC_QRDecodedBitStreamParser::~CBC_QRDecodedBitStreamParser() {} +CBC_CommonDecoderResult* CBC_QRDecodedBitStreamParser::Decode( + CFX_ByteArray* bytes, + CBC_QRCoderVersion* version, + CBC_QRCoderErrorCorrectionLevel* ecLevel, + int32_t byteModeDecode, + int32_t& e) { + CBC_CommonBitSource bits(bytes); + CFX_ByteString result; + CBC_CommonCharacterSetECI* currentCharacterSetECI = NULL; + FX_BOOL fc1Infact = FALSE; + CFX_Int32Array byteSegments; + CBC_QRCoderMode* mode = NULL; + do { + if (bits.Available() < 4) { + mode = CBC_QRCoderMode::sTERMINATOR; + } else { + int32_t iTemp1 = bits.ReadBits(4, e); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + mode = CBC_QRCoderMode::ForBits(iTemp1, e); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + if (mode == NULL) { + e = BCExceptionUnSupportMode; + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + } + } + if (!(mode == CBC_QRCoderMode::sTERMINATOR)) { + if (mode == CBC_QRCoderMode::sFNC1_FIRST_POSITION || + mode == CBC_QRCoderMode::sFNC1_SECOND_POSITION) { + fc1Infact = TRUE; + } else if (mode == CBC_QRCoderMode::sSTRUCTURED_APPEND) { + bits.ReadBits(16, e); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + } else if (mode == CBC_QRCoderMode::sECI) { + int32_t value = ParseECIValue(&bits, e); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + currentCharacterSetECI = + CBC_CommonCharacterSetECI::GetCharacterSetECIByValue(value); + } else { + if (mode == CBC_QRCoderMode::sGBK) { + bits.ReadBits(4, e); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + } + int32_t numBits = mode->GetCharacterCountBits(version, e); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + int32_t count = bits.ReadBits(numBits, e); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + if (mode == CBC_QRCoderMode::sNUMERIC) { + DecodeNumericSegment(&bits, result, count, e); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + } else if (mode == CBC_QRCoderMode::sALPHANUMERIC) { + DecodeAlphanumericSegment(&bits, result, count, fc1Infact, e); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + } else if (mode == CBC_QRCoderMode::sBYTE) { + DecodeByteSegment(&bits, result, count, currentCharacterSetECI, + &byteSegments, byteModeDecode, e); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + } else if (mode == CBC_QRCoderMode::sGBK) { + DecodeGBKSegment(&bits, result, count, e); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + } else if (mode == CBC_QRCoderMode::sKANJI) { + DecodeKanjiSegment(&bits, result, count, e); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + } else { + e = BCExceptionUnSupportMode; + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + } + } + } + } while (!(mode == CBC_QRCoderMode::sTERMINATOR)); + CBC_CommonDecoderResult* tempCd = new CBC_CommonDecoderResult(); + tempCd->Init(*bytes, result, byteSegments, ecLevel, e); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + return tempCd; +} +void CBC_QRDecodedBitStreamParser::DecodeGBKSegment(CBC_CommonBitSource* bits, + CFX_ByteString& result, + int32_t count, + int32_t& e) { + CFX_ByteString buffer; + while (count > 0) { + int32_t twoBytes = bits->ReadBits(13, e); + BC_EXCEPTION_CHECK_ReturnVoid(e); + int32_t assembledTwoBytes = ((twoBytes / 0x060) << 8) | (twoBytes % 0x060); + if (assembledTwoBytes <= 0x0095d) { + assembledTwoBytes += 0x0a1a1; + } else { + assembledTwoBytes += 0x0a6a1; + } + buffer += (uint8_t)(assembledTwoBytes >> 8); + buffer += (uint8_t)assembledTwoBytes; + count--; + } + CBC_UtilCodingConvert::LocaleToUtf8(buffer, result); +} +void CBC_QRDecodedBitStreamParser::DecodeKanjiSegment(CBC_CommonBitSource* bits, + CFX_ByteString& result, + int32_t count, + int32_t& e) { + CFX_ByteString buffer; + while (count > 0) { + int32_t twoBytes = bits->ReadBits(13, e); + BC_EXCEPTION_CHECK_ReturnVoid(e); + int32_t assembledTwoBytes = ((twoBytes / 0x0c0) << 8) | (twoBytes % 0x0c0); + if (assembledTwoBytes <= 0x01f00) { + assembledTwoBytes += 0x08140; + } else { + assembledTwoBytes += 0x0c140; + } + buffer += (uint8_t)(assembledTwoBytes >> 8); + buffer += (uint8_t)assembledTwoBytes; + count--; + } + CBC_UtilCodingConvert::LocaleToUtf8(buffer, result); +} +void CBC_QRDecodedBitStreamParser::DecodeByteSegment( + CBC_CommonBitSource* bits, + CFX_ByteString& result, + int32_t count, + CBC_CommonCharacterSetECI* currentCharacterSetECI, + CFX_Int32Array* byteSegments, + int32_t byteModeDecode, + int32_t& e) { + if (count < 0) { + e = BCExceptionNotFound; + BC_EXCEPTION_CHECK_ReturnVoid(e); + } + if ((count << 3) > bits->Available()) { + e = BCExceptionRead; + BC_EXCEPTION_CHECK_ReturnVoid(e); + } + uint8_t* readBytes = FX_Alloc(uint8_t, count); + FXSYS_memset(readBytes, 0x00, count); + for (int32_t i = 0; i < count; i++) { + readBytes[i] = (uint8_t)bits->ReadBits(8, e); + BC_EXCEPTION_CHECK_ReturnVoid(e); + } + CFX_ByteString bs(readBytes, count); + result += bs; + FX_Free(readBytes); +} +void CBC_QRDecodedBitStreamParser::DecodeAlphanumericSegment( + CBC_CommonBitSource* bits, + CFX_ByteString& result, + int32_t count, + FX_BOOL fac1InEffect, + int32_t& e) { + int32_t start = result.GetLength(); + while (count > 1) { + int32_t nextTwoCharsBits = bits->ReadBits(11, e); + BC_EXCEPTION_CHECK_ReturnVoid(e); + BC_FX_ByteString_Append(result, 1, + ALPHANUMERIC_CHARS[nextTwoCharsBits / 45]); + BC_FX_ByteString_Append(result, 1, + ALPHANUMERIC_CHARS[nextTwoCharsBits % 45]); + count -= 2; + } + if (count == 1) { + int32_t itemp = bits->ReadBits(6, e); + BC_EXCEPTION_CHECK_ReturnVoid(e); + BC_FX_ByteString_Append(result, 1, ALPHANUMERIC_CHARS[itemp]); + } + if (fac1InEffect) { + for (int32_t i = start; i < result.GetLength(); i++) { + if (result[i] == '%') { + if ((i < result.GetLength() - 1) && result[i + 1] == '%') { + result.Delete(i + 1, 1); + } else { + result.SetAt(i, (FX_CHAR)0x1d); + } + } + } + } +} +void CBC_QRDecodedBitStreamParser::DecodeNumericSegment( + CBC_CommonBitSource* bits, + CFX_ByteString& result, + int32_t count, + int32_t& e) { + while (count >= 3) { + int32_t threeDigitsBits = bits->ReadBits(10, e); + BC_EXCEPTION_CHECK_ReturnVoid(e); + if (threeDigitsBits >= 1000) { + e = BCExceptionRead; + BC_EXCEPTION_CHECK_ReturnVoid(e); + } + BC_FX_ByteString_Append(result, 1, + ALPHANUMERIC_CHARS[threeDigitsBits / 100]); + BC_FX_ByteString_Append(result, 1, + ALPHANUMERIC_CHARS[(threeDigitsBits / 10) % 10]); + BC_FX_ByteString_Append(result, 1, + ALPHANUMERIC_CHARS[threeDigitsBits % 10]); + count -= 3; + } + if (count == 2) { + int32_t twoDigitBits = bits->ReadBits(7, e); + BC_EXCEPTION_CHECK_ReturnVoid(e); + if (twoDigitBits >= 100) { + e = BCExceptionRead; + BC_EXCEPTION_CHECK_ReturnVoid(e); + } + BC_FX_ByteString_Append(result, 1, ALPHANUMERIC_CHARS[twoDigitBits / 10]); + BC_FX_ByteString_Append(result, 1, ALPHANUMERIC_CHARS[twoDigitBits % 10]); + } else if (count == 1) { + int32_t digitBits = bits->ReadBits(4, e); + BC_EXCEPTION_CHECK_ReturnVoid(e); + if (digitBits >= 10) { + e = BCExceptionRead; + BC_EXCEPTION_CHECK_ReturnVoid(e); + } + BC_FX_ByteString_Append(result, 1, ALPHANUMERIC_CHARS[digitBits]); + } +} +const CFX_ByteString CBC_QRDecodedBitStreamParser::GuessEncoding( + CFX_ByteArray* bytes) { + return *UTF_8; +} +int32_t CBC_QRDecodedBitStreamParser::ParseECIValue(CBC_CommonBitSource* bits, + int32_t& e) { + int32_t firstByte = bits->ReadBits(8, e); + BC_EXCEPTION_CHECK_ReturnValue(e, 0); + if ((firstByte & 0x80) == 0) { + return firstByte & 0x7f; + } else if ((firstByte & 0xc0) == 0x80) { + int32_t secondByte = bits->ReadBits(8, e); + BC_EXCEPTION_CHECK_ReturnValue(e, 0); + return ((firstByte & 0x3f) << 8) | secondByte; + } else if ((firstByte & 0xe0) == 0xc0) { + int32_t secondThirdByte = bits->ReadBits(16, e); + BC_EXCEPTION_CHECK_ReturnValue(e, 0); + return ((firstByte & 0x1f) << 16) | secondThirdByte; + } + e = BCExceptionBadECI; + BC_EXCEPTION_CHECK_ReturnValue(e, 0); + return 0; +} diff --git a/xfa/fxbarcode/qrcode/BC_QRDecodedBitStreamParser.h b/xfa/fxbarcode/qrcode/BC_QRDecodedBitStreamParser.h new file mode 100644 index 0000000000..0943bc0a4e --- /dev/null +++ b/xfa/fxbarcode/qrcode/BC_QRDecodedBitStreamParser.h @@ -0,0 +1,59 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef XFA_FXBARCODE_QRCODE_BC_QRDECODEDBITSTREAMPARSER_H_ +#define XFA_FXBARCODE_QRCODE_BC_QRDECODEDBITSTREAMPARSER_H_ + +class CBC_CommonDecoderResult; +class CBC_QRCoderErrorCorrectionLevel; +class CBC_CommonBitSource; +class CBC_QRCoderVersion; +class CBC_CommonCharacterSetECI; +class CBC_QRDecodedBitStreamParser { + private: + static const FX_CHAR ALPHANUMERIC_CHARS[45]; + static const FX_CHAR* UTF_8; + CBC_QRDecodedBitStreamParser(); + + public: + virtual ~CBC_QRDecodedBitStreamParser(); + static CBC_CommonDecoderResult* Decode( + CFX_ByteArray* bytes, + CBC_QRCoderVersion* version, + CBC_QRCoderErrorCorrectionLevel* ecLevel, + int32_t byteModeDecode, + int32_t& e); + + static const CFX_ByteString GuessEncoding(CFX_ByteArray* bytes); + static int32_t ParseECIValue(CBC_CommonBitSource* bits, int32_t& e); + static void DecodeGBKSegment(CBC_CommonBitSource* bits, + CFX_ByteString& result, + int32_t count, + int32_t& e); + static void DecodeKanjiSegment(CBC_CommonBitSource* bits, + CFX_ByteString& result, + int32_t count, + int32_t& e); + static void DecodeNumericSegment(CBC_CommonBitSource* bits, + CFX_ByteString& result, + int32_t count, + int32_t& e); + static void DecodeAlphanumericSegment(CBC_CommonBitSource* bits, + CFX_ByteString& result, + int32_t count, + FX_BOOL fac1InEffect, + int32_t& e); + static void DecodeByteSegment( + CBC_CommonBitSource* bits, + CFX_ByteString& result, + int32_t count, + CBC_CommonCharacterSetECI* currentCharacterSetECI, + CFX_Int32Array* byteSegments, + int32_t byteModeDecode, + int32_t& e); +}; + +#endif // XFA_FXBARCODE_QRCODE_BC_QRDECODEDBITSTREAMPARSER_H_ diff --git a/xfa/fxbarcode/qrcode/BC_QRDetector.cpp b/xfa/fxbarcode/qrcode/BC_QRDetector.cpp new file mode 100644 index 0000000000..030ee43c20 --- /dev/null +++ b/xfa/fxbarcode/qrcode/BC_QRDetector.cpp @@ -0,0 +1,278 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com +// Original code is licensed as follows: +/* + * Copyright 2007 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "xfa/fxbarcode/qrcode/BC_QRDetector.h" + +#include <algorithm> +#include <memory> + +#include "xfa/fxbarcode/BC_ResultPoint.h" +#include "xfa/fxbarcode/common/BC_CommonBitMatrix.h" +#include "xfa/fxbarcode/qrcode/BC_FinderPatternInfo.h" +#include "xfa/fxbarcode/qrcode/BC_QRAlignmentPatternFinder.h" +#include "xfa/fxbarcode/qrcode/BC_QRCoderVersion.h" +#include "xfa/fxbarcode/qrcode/BC_QRDetectorResult.h" +#include "xfa/fxbarcode/qrcode/BC_QRFinderPattern.h" +#include "xfa/fxbarcode/qrcode/BC_QRFinderPatternFinder.h" +#include "xfa/fxbarcode/qrcode/BC_QRGridSampler.h" + +CBC_QRDetector::CBC_QRDetector(CBC_CommonBitMatrix* image) : m_image(image) {} +CBC_QRDetector::~CBC_QRDetector() {} +CBC_QRDetectorResult* CBC_QRDetector::Detect(int32_t hints, int32_t& e) { + CBC_QRFinderPatternFinder finder(m_image); + std::unique_ptr<CBC_QRFinderPatternInfo> info(finder.Find(hints, e)); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + CBC_QRDetectorResult* qdr = ProcessFinderPatternInfo(info.get(), e); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + return qdr; +} +CBC_QRDetectorResult* CBC_QRDetector::ProcessFinderPatternInfo( + CBC_QRFinderPatternInfo* info, + int32_t& e) { + std::unique_ptr<CBC_QRFinderPattern> topLeft(info->GetTopLeft()); + std::unique_ptr<CBC_QRFinderPattern> topRight(info->GetTopRight()); + std::unique_ptr<CBC_QRFinderPattern> bottomLeft(info->GetBottomLeft()); + FX_FLOAT moduleSize = + CalculateModuleSize(topLeft.get(), topRight.get(), bottomLeft.get()); + if (moduleSize < 1.0f) { + e = BCExceptionRead; + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + } + int32_t dimension = ComputeDimension(topLeft.get(), topRight.get(), + bottomLeft.get(), moduleSize, e); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + CBC_QRCoderVersion* provisionalVersion = + CBC_QRCoderVersion::GetProvisionalVersionForDimension(dimension, e); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + int32_t modulesBetweenFPCenters = + provisionalVersion->GetDimensionForVersion() - 7; + CBC_QRAlignmentPattern* alignmentPattern = NULL; + if (provisionalVersion->GetAlignmentPatternCenters()->GetSize() > 0) { + FX_FLOAT bottomRightX = + topRight->GetX() - topLeft->GetX() + bottomLeft->GetX(); + FX_FLOAT bottomRightY = + topRight->GetY() - topLeft->GetY() + bottomLeft->GetY(); + FX_FLOAT correctionToTopLeft = + 1.0f - 3.0f / (FX_FLOAT)modulesBetweenFPCenters; + FX_FLOAT xtemp = (topLeft->GetX() + + correctionToTopLeft * (bottomRightX - topLeft->GetX())); + int32_t estAlignmentX = (int32_t)xtemp; + FX_FLOAT ytemp = (topLeft->GetY() + + correctionToTopLeft * (bottomRightY - topLeft->GetY())); + int32_t estAlignmentY = (int32_t)ytemp; + for (int32_t i = 4; i <= 16; i <<= 1) { + CBC_QRAlignmentPattern* temp = FindAlignmentInRegion( + moduleSize, estAlignmentX, estAlignmentY, (FX_FLOAT)i, e); + alignmentPattern = temp; + break; + } + } + CBC_CommonBitMatrix* bits = + SampleGrid(m_image, topLeft.get(), topRight.get(), bottomLeft.get(), + (CBC_ResultPoint*)(alignmentPattern), dimension, e); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + CFX_PtrArray* points = new CFX_PtrArray; + if (alignmentPattern == NULL) { + points->Add(bottomLeft.release()); + points->Add(topLeft.release()); + points->Add(topRight.release()); + } else { + points->Add(bottomLeft.release()); + points->Add(topLeft.release()); + points->Add(topRight.release()); + points->Add(alignmentPattern); + } + return new CBC_QRDetectorResult(bits, points); +} +CBC_CommonBitMatrix* CBC_QRDetector::SampleGrid( + CBC_CommonBitMatrix* image, + CBC_ResultPoint* topLeft, + CBC_ResultPoint* topRight, + CBC_ResultPoint* bottomLeft, + CBC_ResultPoint* alignmentPattern, + int32_t dimension, + int32_t& e) { + FX_FLOAT dimMinusThree = (FX_FLOAT)dimension - 3.5f; + FX_FLOAT bottomRightX; + FX_FLOAT bottomRightY; + FX_FLOAT sourceBottomRightX; + FX_FLOAT sourceBottomRightY; + if (alignmentPattern) { + bottomRightX = alignmentPattern->GetX(); + bottomRightY = alignmentPattern->GetY(); + sourceBottomRightX = sourceBottomRightY = dimMinusThree - 3.0f; + } else { + bottomRightX = (topRight->GetX() - topLeft->GetX()) + bottomLeft->GetX(); + bottomRightY = (topRight->GetY() - topLeft->GetY()) + bottomLeft->GetY(); + sourceBottomRightX = sourceBottomRightY = dimMinusThree; + } + CBC_QRGridSampler& sampler = CBC_QRGridSampler::GetInstance(); + CBC_CommonBitMatrix* cbm = sampler.SampleGrid( + image, dimension, dimension, 3.5f, 3.5f, dimMinusThree, 3.5f, + sourceBottomRightX, sourceBottomRightY, 3.5f, dimMinusThree, + topLeft->GetX(), topLeft->GetY(), topRight->GetX(), topRight->GetY(), + bottomRightX, bottomRightY, bottomLeft->GetX(), bottomLeft->GetY(), e); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + return cbm; +} +int32_t CBC_QRDetector::ComputeDimension(CBC_ResultPoint* topLeft, + CBC_ResultPoint* topRight, + CBC_ResultPoint* bottomLeft, + FX_FLOAT moduleSize, + int32_t& e) { + int32_t tltrCentersDimension = Round( + CBC_QRFinderPatternFinder::Distance(topLeft, topRight) / moduleSize); + int32_t tlblCentersDimension = Round( + CBC_QRFinderPatternFinder::Distance(topLeft, bottomLeft) / moduleSize); + int32_t dimension = ((tltrCentersDimension + tlblCentersDimension) >> 1) + 7; + switch (dimension & 0x03) { + case 0: + dimension++; + break; + case 2: + dimension--; + break; + case 3: { + e = BCExceptionRead; + BC_EXCEPTION_CHECK_ReturnValue(e, 0); + } + } + return dimension; +} +FX_FLOAT CBC_QRDetector::CalculateModuleSize(CBC_ResultPoint* topLeft, + CBC_ResultPoint* topRight, + CBC_ResultPoint* bottomLeft) { + return (CalculateModuleSizeOneWay(topLeft, topRight) + + CalculateModuleSizeOneWay(topLeft, bottomLeft)) / + 2.0f; +} +FX_FLOAT CBC_QRDetector::CalculateModuleSizeOneWay( + CBC_ResultPoint* pattern, + CBC_ResultPoint* otherPattern) { + FX_FLOAT moduleSizeEst1 = SizeOfBlackWhiteBlackRunBothWays( + (int32_t)pattern->GetX(), (int32_t)pattern->GetY(), + (int32_t)otherPattern->GetX(), (int32_t)otherPattern->GetY()); + FX_FLOAT moduleSizeEst2 = SizeOfBlackWhiteBlackRunBothWays( + (int32_t)otherPattern->GetX(), (int32_t)otherPattern->GetY(), + (int32_t)pattern->GetX(), (int32_t)pattern->GetY()); + if (FXSYS_isnan(moduleSizeEst1)) { + return moduleSizeEst2; + } + if (FXSYS_isnan(moduleSizeEst2)) { + return moduleSizeEst1; + } + return (moduleSizeEst1 + moduleSizeEst2) / 14.0f; +} +int32_t CBC_QRDetector::Round(FX_FLOAT d) { + return (int32_t)(d + 0.5f); +} +FX_FLOAT CBC_QRDetector::SizeOfBlackWhiteBlackRunBothWays(int32_t fromX, + int32_t fromY, + int32_t toX, + int32_t toY) { + FX_FLOAT result = SizeOfBlackWhiteBlackRun(fromX, fromY, toX, toY); + int32_t otherToX = fromX - (toX - fromX); + if (otherToX < 0) { + otherToX = -1; + } else if (otherToX >= m_image->GetWidth()) { + otherToX = m_image->GetWidth(); + } + int32_t otherToY = fromY - (toY - fromY); + if (otherToY < 0) { + otherToY = -1; + } else if (otherToY >= m_image->GetHeight()) { + otherToY = m_image->GetHeight(); + } + result += SizeOfBlackWhiteBlackRun(fromX, fromY, otherToX, otherToY); + return result - 1.0f; +} +FX_FLOAT CBC_QRDetector::SizeOfBlackWhiteBlackRun(int32_t fromX, + int32_t fromY, + int32_t toX, + int32_t toY) { + FX_BOOL steep = FXSYS_abs(toY - fromY) > FXSYS_abs(toX - fromX); + if (steep) { + int32_t temp = fromX; + fromX = fromY; + fromY = temp; + temp = toX; + toX = toY; + toY = temp; + } + int32_t dx = FXSYS_abs(toX - fromX); + int32_t dy = FXSYS_abs(toY - fromY); + int32_t error = -dx >> 1; + int32_t ystep = fromY < toY ? 1 : -1; + int32_t xstep = fromX < toX ? 1 : -1; + int32_t state = 0; + for (int32_t x = fromX, y = fromY; x != toX; x += xstep) { + int32_t realX = steep ? y : x; + int32_t realY = steep ? x : y; + if (state == 1) { + if (m_image->Get(realX, realY)) { + state++; + } + } else { + if (!m_image->Get(realX, realY)) { + state++; + } + } + if (state == 3) { + int32_t diffX = x - fromX; + int32_t diffY = y - fromY; + return (FX_FLOAT)sqrt((double)(diffX * diffX + diffY * diffY)); + } + error += dy; + if (error > 0) { + y += ystep; + error -= dx; + } + } + int32_t diffX = toX - fromX; + int32_t diffY = toY - fromY; + return (FX_FLOAT)sqrt((double)(diffX * diffX + diffY * diffY)); +} +CBC_QRAlignmentPattern* CBC_QRDetector::FindAlignmentInRegion( + FX_FLOAT overallEstModuleSize, + int32_t estAlignmentX, + int32_t estAlignmentY, + FX_FLOAT allowanceFactor, + int32_t& e) { + int32_t allowance = (int32_t)(allowanceFactor * overallEstModuleSize); + int32_t alignmentAreaLeftX = std::max(0, estAlignmentX - allowance); + int32_t alignmentAreaRightX = + std::min(m_image->GetWidth() - 1, estAlignmentX + allowance); + if (alignmentAreaRightX - alignmentAreaLeftX < overallEstModuleSize * 3) { + e = BCExceptionRead; + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + } + int32_t alignmentAreaTopY = std::max(0, estAlignmentY - allowance); + int32_t alignmentAreaBottomY = + std::min(m_image->GetHeight() - 1, estAlignmentY + allowance); + CBC_QRAlignmentPatternFinder alignmentFinder( + m_image, alignmentAreaLeftX, alignmentAreaTopY, + alignmentAreaRightX - alignmentAreaLeftX, + alignmentAreaBottomY - alignmentAreaTopY, overallEstModuleSize); + CBC_QRAlignmentPattern* qap = alignmentFinder.Find(e); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + return qap; +} diff --git a/xfa/fxbarcode/qrcode/BC_QRDetector.h b/xfa/fxbarcode/qrcode/BC_QRDetector.h new file mode 100644 index 0000000000..4c171847cb --- /dev/null +++ b/xfa/fxbarcode/qrcode/BC_QRDetector.h @@ -0,0 +1,63 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef XFA_FXBARCODE_QRCODE_BC_QRDETECTOR_H_ +#define XFA_FXBARCODE_QRCODE_BC_QRDETECTOR_H_ + +#include "core/include/fxcrt/fx_basic.h" + +class CBC_ResultPoint; +class CBC_CommonBitMatrix; +class CBC_QRDetectorResult; +class CBC_QRFinderPatternInfo; +class CBC_QRAlignmentPattern; + +class CBC_QRDetector { + private: + CBC_CommonBitMatrix* m_image; + + public: + CBC_QRDetector(CBC_CommonBitMatrix* image); + virtual ~CBC_QRDetector(); + + CBC_CommonBitMatrix* GetImage(); + CBC_QRDetectorResult* Detect(int32_t hints, int32_t& e); + CBC_QRDetectorResult* ProcessFinderPatternInfo(CBC_QRFinderPatternInfo* info, + int32_t& e); + FX_FLOAT CalculateModuleSize(CBC_ResultPoint* topLeft, + CBC_ResultPoint* topRight, + CBC_ResultPoint* bottomLeft); + FX_FLOAT CalculateModuleSizeOneWay(CBC_ResultPoint* pattern, + CBC_ResultPoint* otherPattern); + FX_FLOAT SizeOfBlackWhiteBlackRunBothWays(int32_t fromX, + int32_t fromY, + int32_t toX, + int32_t toY); + FX_FLOAT SizeOfBlackWhiteBlackRun(int32_t fromX, + int32_t fromY, + int32_t toX, + int32_t toY); + CBC_QRAlignmentPattern* FindAlignmentInRegion(FX_FLOAT overallEstModuleSize, + int32_t estAlignmentX, + int32_t estAlignmentY, + FX_FLOAT allowanceFactor, + int32_t& e); + static int32_t Round(FX_FLOAT d); + static int32_t ComputeDimension(CBC_ResultPoint* topLeft, + CBC_ResultPoint* topRight, + CBC_ResultPoint* bottomLeft, + FX_FLOAT moduleSize, + int32_t& e); + static CBC_CommonBitMatrix* SampleGrid(CBC_CommonBitMatrix* image, + CBC_ResultPoint* topLeft, + CBC_ResultPoint* topRight, + CBC_ResultPoint* bottomLeft, + CBC_ResultPoint* alignmentPattern, + int32_t dimension, + int32_t& e); +}; + +#endif // XFA_FXBARCODE_QRCODE_BC_QRDETECTOR_H_ diff --git a/xfa/fxbarcode/qrcode/BC_QRDetectorResult.cpp b/xfa/fxbarcode/qrcode/BC_QRDetectorResult.cpp new file mode 100644 index 0000000000..18e5d9ad4c --- /dev/null +++ b/xfa/fxbarcode/qrcode/BC_QRDetectorResult.cpp @@ -0,0 +1,43 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com +// Original code is licensed as follows: +/* + * Copyright 2007 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "xfa/fxbarcode/BC_ResultPoint.h" +#include "xfa/fxbarcode/common/BC_CommonBitMatrix.h" +#include "xfa/fxbarcode/qrcode/BC_QRDetectorResult.h" + +CBC_QRDetectorResult::CBC_QRDetectorResult(CBC_CommonBitMatrix* bits, + CFX_PtrArray* points) + : m_bits(bits), m_points(points) {} +CBC_QRDetectorResult::~CBC_QRDetectorResult() { + for (int32_t i = 0; i < m_points->GetSize(); i++) { + delete (CBC_ResultPoint*)(*m_points)[i]; + } + m_points->RemoveAll(); + delete m_points; + delete m_bits; +} +CBC_CommonBitMatrix* CBC_QRDetectorResult::GetBits() { + return m_bits; +} +CFX_PtrArray* CBC_QRDetectorResult::GetPoints() { + return m_points; +} diff --git a/xfa/fxbarcode/qrcode/BC_QRDetectorResult.h b/xfa/fxbarcode/qrcode/BC_QRDetectorResult.h new file mode 100644 index 0000000000..c6145ecbbe --- /dev/null +++ b/xfa/fxbarcode/qrcode/BC_QRDetectorResult.h @@ -0,0 +1,26 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef XFA_FXBARCODE_QRCODE_BC_QRDETECTORRESULT_H_ +#define XFA_FXBARCODE_QRCODE_BC_QRDETECTORRESULT_H_ + +#include "core/include/fxcrt/fx_basic.h" + +class CBC_CommonBitMatrix; + +class CBC_QRDetectorResult { + private: + CBC_CommonBitMatrix* m_bits; + CFX_PtrArray* m_points; + + public: + CBC_QRDetectorResult(CBC_CommonBitMatrix* bits, CFX_PtrArray* points); + virtual ~CBC_QRDetectorResult(); + CBC_CommonBitMatrix* GetBits(); + CFX_PtrArray* GetPoints(); +}; + +#endif // XFA_FXBARCODE_QRCODE_BC_QRDETECTORRESULT_H_ diff --git a/xfa/fxbarcode/qrcode/BC_QRFinderPattern.cpp b/xfa/fxbarcode/qrcode/BC_QRFinderPattern.cpp new file mode 100644 index 0000000000..5039920e32 --- /dev/null +++ b/xfa/fxbarcode/qrcode/BC_QRFinderPattern.cpp @@ -0,0 +1,68 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com +// Original code is licensed as follows: +/* + * Copyright 2007 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "xfa/fxbarcode/BC_ResultPoint.h" +#include "xfa/fxbarcode/qrcode/BC_QRFinderPattern.h" + +CBC_QRFinderPattern::CBC_QRFinderPattern(FX_FLOAT x, + FX_FLOAT posY, + FX_FLOAT estimatedModuleSize) + : CBC_ResultPoint(x, posY), + m_estimatedModuleSize(estimatedModuleSize), + m_count(1) {} +CBC_QRFinderPattern::~CBC_QRFinderPattern() { + m_count = 0; + m_x = 0.0f; + m_y = 0.0f; + m_estimatedModuleSize = 0.0f; +} +CBC_QRFinderPattern* CBC_QRFinderPattern::Clone() { + CBC_QRFinderPattern* temp = + new CBC_QRFinderPattern(m_x, m_y, m_estimatedModuleSize); + temp->m_count = m_count; + return temp; +} +FX_FLOAT CBC_QRFinderPattern::GetEstimatedModuleSize() { + return m_estimatedModuleSize; +} +int32_t CBC_QRFinderPattern::GetCount() { + return m_count; +} +void CBC_QRFinderPattern::IncrementCount() { + m_count++; +} +FX_BOOL CBC_QRFinderPattern::AboutEquals(FX_FLOAT moduleSize, + FX_FLOAT i, + FX_FLOAT j) { + if ((fabs(i - GetY()) <= moduleSize) && (fabs(j - GetX()) <= moduleSize)) { + FX_FLOAT moduleSizeDiff = fabs(moduleSize - m_estimatedModuleSize); + return (moduleSizeDiff <= 1.0f) || + (moduleSizeDiff / m_estimatedModuleSize <= 1.0f); + } + return false; +} +FX_FLOAT CBC_QRFinderPattern::GetX() { + return m_x; +} +FX_FLOAT CBC_QRFinderPattern::GetY() { + return m_y; +} diff --git a/xfa/fxbarcode/qrcode/BC_QRFinderPattern.h b/xfa/fxbarcode/qrcode/BC_QRFinderPattern.h new file mode 100644 index 0000000000..bf3adffea4 --- /dev/null +++ b/xfa/fxbarcode/qrcode/BC_QRFinderPattern.h @@ -0,0 +1,31 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef XFA_FXBARCODE_QRCODE_BC_QRFINDERPATTERN_H_ +#define XFA_FXBARCODE_QRCODE_BC_QRFINDERPATTERN_H_ + +class CBC_ResultPoint; +class CBC_QRFinderPattern; +class CBC_QRFinderPattern : public CBC_ResultPoint { + private: + FX_FLOAT m_estimatedModuleSize; + int32_t m_count; + + public: + CBC_QRFinderPattern(FX_FLOAT x, FX_FLOAT posY, FX_FLOAT estimatedModuleSize); + virtual ~CBC_QRFinderPattern(); + + int32_t GetCount(); + FX_FLOAT GetX(); + FX_FLOAT GetY(); + FX_FLOAT GetEstimatedModuleSize(); + void IncrementCount(); + FX_BOOL AboutEquals(FX_FLOAT moduleSize, FX_FLOAT i, FX_FLOAT j); + CBC_QRFinderPattern* Clone(); +}; +typedef CBC_QRFinderPattern FinderPattern; + +#endif // XFA_FXBARCODE_QRCODE_BC_QRFINDERPATTERN_H_ diff --git a/xfa/fxbarcode/qrcode/BC_QRFinderPatternFinder.cpp b/xfa/fxbarcode/qrcode/BC_QRFinderPatternFinder.cpp new file mode 100644 index 0000000000..5ccbd9804b --- /dev/null +++ b/xfa/fxbarcode/qrcode/BC_QRFinderPatternFinder.cpp @@ -0,0 +1,477 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com +// Original code is licensed as follows: +/* + * Copyright 2007 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "xfa/fxbarcode/qrcode/BC_QRFinderPatternFinder.h" + +#include <memory> + +#include "core/include/fxcrt/fx_basic.h" +#include "xfa/fxbarcode/BC_ResultPoint.h" +#include "xfa/fxbarcode/common/BC_CommonBitMatrix.h" +#include "xfa/fxbarcode/qrcode/BC_FinderPatternInfo.h" +#include "xfa/fxbarcode/qrcode/BC_QRFinderPattern.h" +#include "xfa/fxbarcode/utils.h" + +const int32_t CBC_QRFinderPatternFinder::CENTER_QUORUM = 2; +const int32_t CBC_QRFinderPatternFinder::MIN_SKIP = 3; +const int32_t CBC_QRFinderPatternFinder::MAX_MODULES = 57; +const int32_t CBC_QRFinderPatternFinder::INTEGER_MATH_SHIFT = 8; + +CBC_QRFinderPatternFinder::CBC_QRFinderPatternFinder( + CBC_CommonBitMatrix* image) { + m_image = image; + m_crossCheckStateCount.SetSize(5); + m_hasSkipped = FALSE; +} +CBC_QRFinderPatternFinder::~CBC_QRFinderPatternFinder() { + for (int32_t i = 0; i < m_possibleCenters.GetSize(); i++) { + delete (CBC_QRFinderPattern*)m_possibleCenters[i]; + } + m_possibleCenters.RemoveAll(); +} +class ClosestToAverageComparator { + private: + FX_FLOAT m_averageModuleSize; + + public: + ClosestToAverageComparator(FX_FLOAT averageModuleSize) + : m_averageModuleSize(averageModuleSize) {} + int32_t operator()(FinderPattern* a, FinderPattern* b) { + FX_FLOAT dA = + (FX_FLOAT)fabs(a->GetEstimatedModuleSize() - m_averageModuleSize); + FX_FLOAT dB = + (FX_FLOAT)fabs(b->GetEstimatedModuleSize() - m_averageModuleSize); + return dA < dB ? -1 : dA > dB ? 1 : 0; + } +}; +class CenterComparator { + public: + int32_t operator()(FinderPattern* a, FinderPattern* b) { + return b->GetCount() - a->GetCount(); + } +}; +CBC_CommonBitMatrix* CBC_QRFinderPatternFinder::GetImage() { + return m_image; +} +CFX_Int32Array& CBC_QRFinderPatternFinder::GetCrossCheckStateCount() { + m_crossCheckStateCount[0] = 0; + m_crossCheckStateCount[1] = 0; + m_crossCheckStateCount[2] = 0; + m_crossCheckStateCount[3] = 0; + m_crossCheckStateCount[4] = 0; + return m_crossCheckStateCount; +} +CFX_PtrArray* CBC_QRFinderPatternFinder::GetPossibleCenters() { + return &m_possibleCenters; +} +CBC_QRFinderPatternInfo* CBC_QRFinderPatternFinder::Find(int32_t hint, + int32_t& e) { + int32_t maxI = m_image->GetHeight(); + int32_t maxJ = m_image->GetWidth(); + int32_t iSkip = (3 * maxI) / (4 * MAX_MODULES); + if (iSkip < MIN_SKIP || 0) { + iSkip = MIN_SKIP; + } + FX_BOOL done = FALSE; + CFX_Int32Array stateCount; + stateCount.SetSize(5); + for (int32_t i = iSkip - 1; i < maxI && !done; i += iSkip) { + stateCount[0] = 0; + stateCount[1] = 0; + stateCount[2] = 0; + stateCount[3] = 0; + stateCount[4] = 0; + int32_t currentState = 0; + for (int32_t j = 0; j < maxJ; j++) { + if (m_image->Get(j, i)) { + if ((currentState & 1) == 1) { + currentState++; + } + stateCount[currentState]++; + } else { + if ((currentState & 1) == 0) { + if (currentState == 4) { + if (FoundPatternCross(stateCount)) { + FX_BOOL confirmed = HandlePossibleCenter(stateCount, i, j); + if (confirmed) { + iSkip = 2; + if (m_hasSkipped) { + done = HaveMultiplyConfirmedCenters(); + } else { + int32_t rowSkip = FindRowSkip(); + if (rowSkip > stateCount[2]) { + i += rowSkip - stateCount[2] - iSkip; + j = maxJ - 1; + } + } + } else { + do { + j++; + } while (j < maxJ && !m_image->Get(j, i)); + j--; + } + currentState = 0; + stateCount[0] = 0; + stateCount[1] = 0; + stateCount[2] = 0; + stateCount[3] = 0; + stateCount[4] = 0; + } else { + stateCount[0] = stateCount[2]; + stateCount[1] = stateCount[3]; + stateCount[2] = stateCount[4]; + stateCount[3] = 1; + stateCount[4] = 0; + currentState = 3; + } + } else { + stateCount[++currentState]++; + } + } else { + stateCount[currentState]++; + } + } + } + if (FoundPatternCross(stateCount)) { + FX_BOOL confirmed = HandlePossibleCenter(stateCount, i, maxJ); + if (confirmed) { + iSkip = stateCount[0]; + if (m_hasSkipped) { + done = HaveMultiplyConfirmedCenters(); + } + } + } + } + std::unique_ptr<CFX_PtrArray> patternInfo(SelectBestpatterns(e)); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + OrderBestPatterns(patternInfo.get()); + return new CBC_QRFinderPatternInfo(patternInfo.get()); +} +void CBC_QRFinderPatternFinder::OrderBestPatterns(CFX_PtrArray* patterns) { + FX_FLOAT abDistance = Distance((CBC_ResultPoint*)(*patterns)[0], + (CBC_ResultPoint*)(*patterns)[1]); + FX_FLOAT bcDistance = Distance((CBC_ResultPoint*)(*patterns)[1], + (CBC_ResultPoint*)(*patterns)[2]); + FX_FLOAT acDistance = Distance((CBC_ResultPoint*)(*patterns)[0], + (CBC_ResultPoint*)(*patterns)[2]); + CBC_QRFinderPattern *topLeft, *topRight, *bottomLeft; + if (bcDistance >= abDistance && bcDistance >= acDistance) { + topLeft = (CBC_QRFinderPattern*)(*patterns)[0]; + topRight = (CBC_QRFinderPattern*)(*patterns)[1]; + bottomLeft = (CBC_QRFinderPattern*)(*patterns)[2]; + } else if (acDistance >= bcDistance && acDistance >= abDistance) { + topLeft = (CBC_QRFinderPattern*)(*patterns)[1]; + topRight = (CBC_QRFinderPattern*)(*patterns)[0]; + bottomLeft = (CBC_QRFinderPattern*)(*patterns)[2]; + } else { + topLeft = (CBC_QRFinderPattern*)(*patterns)[2]; + topRight = (CBC_QRFinderPattern*)(*patterns)[0]; + bottomLeft = (CBC_QRFinderPattern*)(*patterns)[1]; + } + if ((bottomLeft->GetY() - topLeft->GetY()) * + (topRight->GetX() - topLeft->GetX()) < + (bottomLeft->GetX() - topLeft->GetX()) * + (topRight->GetY() - topLeft->GetY())) { + CBC_QRFinderPattern* temp = topRight; + topRight = bottomLeft; + bottomLeft = temp; + } + (*patterns)[0] = bottomLeft; + (*patterns)[1] = topLeft; + (*patterns)[2] = topRight; +} +FX_FLOAT CBC_QRFinderPatternFinder::Distance(CBC_ResultPoint* point1, + CBC_ResultPoint* point2) { + FX_FLOAT dx = point1->GetX() - point2->GetX(); + FX_FLOAT dy = point1->GetY() - point2->GetY(); + return (FX_FLOAT)FXSYS_sqrt(dx * dx + dy * dy); +} +FX_FLOAT CBC_QRFinderPatternFinder::CenterFromEnd( + const CFX_Int32Array& stateCount, + int32_t end) { + return (FX_FLOAT)(end - stateCount[4] - stateCount[3]) - stateCount[2] / 2.0f; +} +FX_BOOL CBC_QRFinderPatternFinder::FoundPatternCross( + const CFX_Int32Array& stateCount) { + int32_t totalModuleSize = 0; + for (int32_t i = 0; i < 5; i++) { + int32_t count = stateCount[i]; + if (count == 0) { + return FALSE; + } + totalModuleSize += count; + } + if (totalModuleSize < 7) { + return FALSE; + } + int32_t moduleSize = (totalModuleSize << INTEGER_MATH_SHIFT) / 7; + int32_t maxVariance = moduleSize / 2; + return FXSYS_abs(moduleSize - (stateCount[0] << INTEGER_MATH_SHIFT)) < + maxVariance && + FXSYS_abs(moduleSize - (stateCount[1] << INTEGER_MATH_SHIFT)) < + maxVariance && + FXSYS_abs(3 * moduleSize - (stateCount[2] << INTEGER_MATH_SHIFT)) < + 3 * maxVariance && + FXSYS_abs(moduleSize - (stateCount[3] << INTEGER_MATH_SHIFT)) < + maxVariance && + FXSYS_abs(moduleSize - (stateCount[4] << INTEGER_MATH_SHIFT)) < + maxVariance; +} +FX_FLOAT CBC_QRFinderPatternFinder::CrossCheckVertical( + int32_t startI, + int32_t centerJ, + int32_t maxCount, + int32_t originalStateCountTotal) { + CBC_CommonBitMatrix* image = m_image; + int32_t maxI = image->GetHeight(); + CFX_Int32Array& stateCount = GetCrossCheckStateCount(); + int32_t i = startI; + while (i >= 0 && image->Get(centerJ, i)) { + stateCount[2]++; + i--; + } + if (i < 0) { + return FXSYS_nan(); + } + while (i >= 0 && !image->Get(centerJ, i) && stateCount[1] <= maxCount) { + stateCount[1]++; + i--; + } + if (i < 0 || stateCount[1] > maxCount) { + return FXSYS_nan(); + } + while (i >= 0 && image->Get(centerJ, i) && stateCount[0] <= maxCount) { + stateCount[0]++; + i--; + } + if (stateCount[0] > maxCount) { + return FXSYS_nan(); + } + i = startI + 1; + while (i < maxI && image->Get(centerJ, i)) { + stateCount[2]++; + i++; + } + if (i == maxI) { + return FXSYS_nan(); + } + while (i < maxI && !image->Get(centerJ, i) && stateCount[3] < maxCount) { + stateCount[3]++; + i++; + } + if (i == maxI || stateCount[3] >= maxCount) { + return FXSYS_nan(); + } + while (i < maxI && image->Get(centerJ, i) && stateCount[4] < maxCount) { + stateCount[4]++; + i++; + } + if (stateCount[4] >= maxCount) { + return FXSYS_nan(); + } + int32_t stateCountTotal = stateCount[0] + stateCount[1] + stateCount[2] + + stateCount[3] + stateCount[4]; + if (5 * FXSYS_abs(stateCountTotal - originalStateCountTotal) >= + originalStateCountTotal) { + return FXSYS_nan(); + } + return FoundPatternCross(stateCount) ? CenterFromEnd(stateCount, i) + : FXSYS_nan(); +} +FX_FLOAT CBC_QRFinderPatternFinder::CrossCheckHorizontal( + int32_t startJ, + int32_t centerI, + int32_t maxCount, + int32_t originalStateCountTotal) { + CBC_CommonBitMatrix* image = m_image; + int32_t maxJ = image->GetWidth(); + CFX_Int32Array& stateCount = GetCrossCheckStateCount(); + int32_t j = startJ; + while (j >= 0 && image->Get(j, centerI)) { + stateCount[2]++; + j--; + } + if (j < 0) { + return FXSYS_nan(); + } + while (j >= 0 && !image->Get(j, centerI) && stateCount[1] <= maxCount) { + stateCount[1]++; + j--; + } + if (j < 0 || stateCount[1] > maxCount) { + return FXSYS_nan(); + } + while (j >= 0 && image->Get(j, centerI) && stateCount[0] <= maxCount) { + stateCount[0]++; + j--; + } + if (stateCount[0] > maxCount) { + return FXSYS_nan(); + } + j = startJ + 1; + while (j < maxJ && image->Get(j, centerI)) { + stateCount[2]++; + j++; + } + if (j == maxJ) { + return FXSYS_nan(); + } + while (j < maxJ && !image->Get(j, centerI) && stateCount[3] < maxCount) { + stateCount[3]++; + j++; + } + if (j == maxJ || stateCount[3] >= maxCount) { + return FXSYS_nan(); + } + while (j < maxJ && image->Get(j, centerI) && stateCount[4] < maxCount) { + stateCount[4]++; + j++; + } + if (stateCount[4] >= maxCount) { + return FXSYS_nan(); + } + int32_t stateCountTotal = stateCount[0] + stateCount[1] + stateCount[2] + + stateCount[3] + stateCount[4]; + if (5 * FXSYS_abs(stateCountTotal - originalStateCountTotal) >= + originalStateCountTotal) { + return FXSYS_nan(); + } + return FoundPatternCross(stateCount) ? CenterFromEnd(stateCount, j) + : FXSYS_nan(); +} +FX_BOOL CBC_QRFinderPatternFinder::HandlePossibleCenter( + const CFX_Int32Array& stateCount, + int32_t i, + int32_t j) { + int32_t stateCountTotal = stateCount[0] + stateCount[1] + stateCount[2] + + stateCount[3] + stateCount[4]; + FX_FLOAT centerJ = CenterFromEnd(stateCount, j); + FX_FLOAT centerI = + CrossCheckVertical(i, (int32_t)centerJ, stateCount[2], stateCountTotal); + if (!FXSYS_isnan(centerI)) { + centerJ = CrossCheckHorizontal((int32_t)centerJ, (int32_t)centerI, + stateCount[2], stateCountTotal); + if (!FXSYS_isnan(centerJ)) { + FX_FLOAT estimatedModuleSize = (FX_FLOAT)stateCountTotal / 7.0f; + FX_BOOL found = FALSE; + int32_t max = m_possibleCenters.GetSize(); + for (int32_t index = 0; index < max; index++) { + CBC_QRFinderPattern* center = + (CBC_QRFinderPattern*)(m_possibleCenters[index]); + if (center->AboutEquals(estimatedModuleSize, centerI, centerJ)) { + center->IncrementCount(); + found = TRUE; + break; + } + } + if (!found) { + m_possibleCenters.Add( + new CBC_QRFinderPattern(centerJ, centerI, estimatedModuleSize)); + } + return TRUE; + } + } + return FALSE; +} +int32_t CBC_QRFinderPatternFinder::FindRowSkip() { + int32_t max = m_possibleCenters.GetSize(); + if (max <= 1) { + return 0; + } + FinderPattern* firstConfirmedCenter = NULL; + for (int32_t i = 0; i < max; i++) { + CBC_QRFinderPattern* center = (CBC_QRFinderPattern*)m_possibleCenters[i]; + if (center->GetCount() >= CENTER_QUORUM) { + if (firstConfirmedCenter == NULL) { + firstConfirmedCenter = center; + } else { + m_hasSkipped = TRUE; + return (int32_t)((fabs(firstConfirmedCenter->GetX() - center->GetX()) - + fabs(firstConfirmedCenter->GetY() - center->GetY())) / + 2); + } + } + } + return 0; +} +FX_BOOL CBC_QRFinderPatternFinder::HaveMultiplyConfirmedCenters() { + int32_t confirmedCount = 0; + FX_FLOAT totalModuleSize = 0.0f; + int32_t max = m_possibleCenters.GetSize(); + int32_t i; + for (i = 0; i < max; i++) { + CBC_QRFinderPattern* pattern = (CBC_QRFinderPattern*)m_possibleCenters[i]; + if (pattern->GetCount() >= CENTER_QUORUM) { + confirmedCount++; + totalModuleSize += pattern->GetEstimatedModuleSize(); + } + } + if (confirmedCount < 3) { + return FALSE; + } + FX_FLOAT average = totalModuleSize / (FX_FLOAT)max; + FX_FLOAT totalDeviation = 0.0f; + for (i = 0; i < max; i++) { + CBC_QRFinderPattern* pattern = (CBC_QRFinderPattern*)m_possibleCenters[i]; + totalDeviation += fabs(pattern->GetEstimatedModuleSize() - average); + } + return totalDeviation <= 0.05f * totalModuleSize; +} +inline FX_BOOL centerComparator(void* a, void* b) { + return ((CBC_QRFinderPattern*)b)->GetCount() < + ((CBC_QRFinderPattern*)a)->GetCount(); +} +CFX_PtrArray* CBC_QRFinderPatternFinder::SelectBestpatterns(int32_t& e) { + int32_t startSize = m_possibleCenters.GetSize(); + if (m_possibleCenters.GetSize() < 3) { + e = BCExceptionRead; + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + } + FX_FLOAT average = 0.0f; + if (startSize > 3) { + FX_FLOAT totalModuleSize = 0.0f; + for (int32_t i = 0; i < startSize; i++) { + totalModuleSize += ((CBC_QRFinderPattern*)m_possibleCenters[i]) + ->GetEstimatedModuleSize(); + } + average = totalModuleSize / (FX_FLOAT)startSize; + for (int32_t j = 0; + j < m_possibleCenters.GetSize() && m_possibleCenters.GetSize() > 3; + j++) { + CBC_QRFinderPattern* pattern = (CBC_QRFinderPattern*)m_possibleCenters[j]; + if (fabs(pattern->GetEstimatedModuleSize() - average) > 0.2f * average) { + delete pattern; + m_possibleCenters.RemoveAt(j); + j--; + } + } + } + if (m_possibleCenters.GetSize() > 3) { + BC_FX_PtrArray_Sort(m_possibleCenters, centerComparator); + } + CFX_PtrArray* vec = new CFX_PtrArray(); + vec->SetSize(3); + (*vec)[0] = ((CBC_QRFinderPattern*)m_possibleCenters[0])->Clone(); + (*vec)[1] = ((CBC_QRFinderPattern*)m_possibleCenters[1])->Clone(); + (*vec)[2] = ((CBC_QRFinderPattern*)m_possibleCenters[2])->Clone(); + return vec; +} diff --git a/xfa/fxbarcode/qrcode/BC_QRFinderPatternFinder.h b/xfa/fxbarcode/qrcode/BC_QRFinderPatternFinder.h new file mode 100644 index 0000000000..058f65df31 --- /dev/null +++ b/xfa/fxbarcode/qrcode/BC_QRFinderPatternFinder.h @@ -0,0 +1,57 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef XFA_FXBARCODE_QRCODE_BC_QRFINDERPATTERNFINDER_H_ +#define XFA_FXBARCODE_QRCODE_BC_QRFINDERPATTERNFINDER_H_ + +#include "core/include/fxcrt/fx_basic.h" + +class CBC_CommonBitMatrix; +class CBC_QRFinderPattern; +class CBC_ResultPoint; +class CBC_QRFinderPatternInfo; + +class CBC_QRFinderPatternFinder { + private: + static const int32_t CENTER_QUORUM; + static const int32_t MIN_SKIP; + static const int32_t MAX_MODULES; + static const int32_t INTEGER_MATH_SHIFT; + FX_BOOL m_hasSkipped; + CBC_CommonBitMatrix* m_image; + CFX_Int32Array m_crossCheckStateCount; + CFX_PtrArray m_possibleCenters; + + public: + CBC_QRFinderPatternFinder(CBC_CommonBitMatrix* image); + virtual ~CBC_QRFinderPatternFinder(); + int32_t FindRowSkip(); + CBC_CommonBitMatrix* GetImage(); + CBC_QRFinderPatternInfo* Find(int32_t hint, int32_t& e); + + CFX_Int32Array& GetCrossCheckStateCount(); + CFX_PtrArray* GetPossibleCenters(); + CFX_PtrArray* SelectBestpatterns(int32_t& e); + + FX_BOOL HandlePossibleCenter(const CFX_Int32Array& stateCount, + int32_t i, + int32_t j); + FX_BOOL HaveMultiplyConfirmedCenters(); + FX_FLOAT CenterFromEnd(const CFX_Int32Array& stateCount, int32_t end); + FX_FLOAT CrossCheckVertical(int32_t startI, + int32_t centerJ, + int32_t maxCount, + int32_t originalStateCountTotal); + FX_FLOAT CrossCheckHorizontal(int32_t startJ, + int32_t CenterI, + int32_t maxCOunt, + int32_t originalStateCountTotal); + static void OrderBestPatterns(CFX_PtrArray* patterns); + static FX_BOOL FoundPatternCross(const CFX_Int32Array& stateCount); + static FX_FLOAT Distance(CBC_ResultPoint* point1, CBC_ResultPoint* point2); +}; + +#endif // XFA_FXBARCODE_QRCODE_BC_QRFINDERPATTERNFINDER_H_ diff --git a/xfa/fxbarcode/qrcode/BC_QRGridSampler.cpp b/xfa/fxbarcode/qrcode/BC_QRGridSampler.cpp new file mode 100644 index 0000000000..881e74a98c --- /dev/null +++ b/xfa/fxbarcode/qrcode/BC_QRGridSampler.cpp @@ -0,0 +1,139 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com +// Original code is licensed as follows: +/* + * Copyright 2007 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "xfa/fxbarcode/qrcode/BC_QRGridSampler.h" + +#include <memory> + +#include "xfa/fxbarcode/common/BC_CommonBitMatrix.h" +#include "xfa/fxbarcode/common/BC_CommonPerspectiveTransform.h" +#include "xfa/fxbarcode/utils.h" + +CBC_QRGridSampler CBC_QRGridSampler::m_gridSampler; + +CBC_QRGridSampler::CBC_QRGridSampler() {} +CBC_QRGridSampler::~CBC_QRGridSampler() {} +CBC_QRGridSampler& CBC_QRGridSampler::GetInstance() { + return m_gridSampler; +} +void CBC_QRGridSampler::CheckAndNudgePoints(CBC_CommonBitMatrix* image, + CFX_FloatArray* points, + int32_t& e) { + int32_t width = image->GetWidth(); + int32_t height = image->GetHeight(); + FX_BOOL nudged = TRUE; + int32_t offset; + for (offset = 0; offset < points->GetSize() && nudged; offset += 2) { + int32_t x = (int32_t)(*points)[offset]; + int32_t y = (int32_t)(*points)[offset + 1]; + if (x < -1 || x > width || y < -1 || y > height) { + e = BCExceptionRead; + BC_EXCEPTION_CHECK_ReturnVoid(e); + } + nudged = FALSE; + if (x == -1) { + (*points)[offset] = 0.0f; + nudged = TRUE; + } else if (x == width) { + (*points)[offset] = (FX_FLOAT)(width - 1); + nudged = TRUE; + } + if (y == -1) { + (*points)[offset + 1] = 0.0f; + nudged = TRUE; + } else if (y == height) { + (*points)[offset + 1] = (FX_FLOAT)(height - 1); + nudged = TRUE; + } + } + nudged = TRUE; + for (offset = (*points).GetSize() - 2; offset >= 0 && nudged; offset -= 2) { + int32_t x = (int32_t)(*points)[offset]; + int32_t y = (int32_t)(*points)[offset + 1]; + if (x < -1 || x > width || y < -1 || y > height) { + e = BCExceptionRead; + BC_EXCEPTION_CHECK_ReturnVoid(e); + } + nudged = FALSE; + if (x == -1) { + (*points)[offset] = 0.0f; + nudged = TRUE; + } else if (x == width) { + (*points)[offset] = (FX_FLOAT)(width - 1); + nudged = TRUE; + } + if (y == -1) { + (*points)[offset + 1] = 0.0f; + nudged = TRUE; + } else if (y == height) { + (*points)[offset + 1] = (FX_FLOAT)(height - 1); + nudged = TRUE; + } + } +} +CBC_CommonBitMatrix* CBC_QRGridSampler::SampleGrid(CBC_CommonBitMatrix* image, + int32_t dimensionX, + int32_t dimensionY, + FX_FLOAT p1ToX, + FX_FLOAT p1ToY, + FX_FLOAT p2ToX, + FX_FLOAT p2ToY, + FX_FLOAT p3ToX, + FX_FLOAT p3ToY, + FX_FLOAT p4ToX, + FX_FLOAT p4ToY, + FX_FLOAT p1FromX, + FX_FLOAT p1FromY, + FX_FLOAT p2FromX, + FX_FLOAT p2FromY, + FX_FLOAT p3FromX, + FX_FLOAT p3FromY, + FX_FLOAT p4FromX, + FX_FLOAT p4FromY, + int32_t& e) { + std::unique_ptr<CBC_CommonPerspectiveTransform> transform( + CBC_CommonPerspectiveTransform::QuadrilateralToQuadrilateral( + p1ToX, p1ToY, p2ToX, p2ToY, p3ToX, p3ToY, p4ToX, p4ToY, p1FromX, + p1FromY, p2FromX, p2FromY, p3FromX, p3FromY, p4FromX, p4FromY)); + std::unique_ptr<CBC_CommonBitMatrix> bits(new CBC_CommonBitMatrix()); + bits->Init(dimensionX, dimensionY); + CFX_FloatArray points; + points.SetSize(dimensionX << 1); + for (int32_t y = 0; y < dimensionY; y++) { + int32_t max = points.GetSize(); + FX_FLOAT iValue = (FX_FLOAT)(y + 0.5f); + int32_t x; + for (x = 0; x < max; x += 2) { + points[x] = (FX_FLOAT)((x >> 1) + 0.5f); + points[x + 1] = iValue; + } + transform->TransformPoints(&points); + CheckAndNudgePoints(image, &points, e); + BC_EXCEPTION_CHECK_ReturnValue(e, NULL); + for (x = 0; x < max; x += 2) { + if (image->Get((int32_t)points[x], (int32_t)points[x + 1])) { + bits->Set(x >> 1, y); + } + } + } + return bits.release(); +} diff --git a/xfa/fxbarcode/qrcode/BC_QRGridSampler.h b/xfa/fxbarcode/qrcode/BC_QRGridSampler.h new file mode 100644 index 0000000000..4e10c5627a --- /dev/null +++ b/xfa/fxbarcode/qrcode/BC_QRGridSampler.h @@ -0,0 +1,48 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef XFA_FXBARCODE_QRCODE_BC_QRGRIDSAMPLER_H_ +#define XFA_FXBARCODE_QRCODE_BC_QRGRIDSAMPLER_H_ + +#include "core/include/fxcrt/fx_basic.h" + +class CBC_CommonBitMatrix; + +class CBC_QRGridSampler { + private: + static CBC_QRGridSampler m_gridSampler; + + public: + CBC_QRGridSampler(); + virtual ~CBC_QRGridSampler(); + virtual CBC_CommonBitMatrix* SampleGrid(CBC_CommonBitMatrix* image, + int32_t dimensionX, + int32_t dimensionY, + FX_FLOAT p1ToX, + FX_FLOAT p1ToY, + FX_FLOAT p2ToX, + FX_FLOAT p2ToY, + FX_FLOAT p3ToX, + FX_FLOAT p3ToY, + FX_FLOAT p4ToX, + FX_FLOAT p4ToY, + FX_FLOAT p1FromX, + FX_FLOAT p1FromY, + FX_FLOAT p2FromX, + FX_FLOAT p2FromY, + FX_FLOAT p3FromX, + FX_FLOAT p3FromY, + FX_FLOAT p4FromX, + FX_FLOAT p4FromY, + int32_t& e); + + static CBC_QRGridSampler& GetInstance(); + static void CheckAndNudgePoints(CBC_CommonBitMatrix* image, + CFX_FloatArray* points, + int32_t& e); +}; + +#endif // XFA_FXBARCODE_QRCODE_BC_QRGRIDSAMPLER_H_ diff --git a/xfa/fxbarcode/utils.h b/xfa/fxbarcode/utils.h new file mode 100644 index 0000000000..f6186e664f --- /dev/null +++ b/xfa/fxbarcode/utils.h @@ -0,0 +1,183 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef XFA_FXBARCODE_UTILS_H_ +#define XFA_FXBARCODE_UTILS_H_ + +#include "core/include/fxcrt/fx_basic.h" + +typedef CFX_MapPtrTemplate<void*, int32_t> CFX_PtrToInt32; +FX_BOOL BC_FX_ByteString_Replace(CFX_ByteString& dst, + FX_DWORD first, + FX_DWORD last, + int32_t count, + FX_CHAR c); +void BC_FX_ByteString_Append(CFX_ByteString& dst, int32_t count, FX_CHAR c); +void BC_FX_ByteString_Append(CFX_ByteString& dst, const CFX_ByteArray& ba); +typedef FX_BOOL (*BC_PtrArrayCompareCallback)(void* l, void* r); +void BC_FX_PtrArray_Sort(CFX_PtrArray& src, BC_PtrArrayCompareCallback fun); + +#if (_FX_OS_ == _FX_WIN32_DESKTOP_ || _FX_OS_ == _FX_WIN64_) +#include <limits> +#elif(_FX_OS_ == _FX_MACOSX_ || _FX_OS_ == _FX_LINUX_DESKTOP_ || \ + _FX_OS_ == _FX_IOS_) +#include <limits.h> +#endif +#if (_FX_OS_ == _FX_WIN32_DESKTOP_ || _FX_OS_ == _FX_WIN64_) +#define FXSYS_isnan(x) _isnan(x) +#elif(_FX_OS_ == _FX_MACOSX_ || _FX_OS_ == _FX_IOS_) +#include <cmath> +#define FXSYS_isnan(x) std::isnan(x) +#elif(_FX_OS_ == _FX_LINUX_DESKTOP_ || _FX_OS_ == _FX_ANDROID_) +#include <math.h> +#define FXSYS_isnan(x) isnan(x) +#endif +#if (_FX_OS_ == _FX_WIN32_DESKTOP_ || _FX_OS_ == _FX_WIN64_) +#define FXSYS_nan() (std::numeric_limits<float>::quiet_NaN()) +#elif(_FX_OS_ == _FX_MACOSX_ || _FX_OS_ == _FX_LINUX_DESKTOP_ || \ + _FX_OS_ == _FX_IOS_ || _FX_OS_ == _FX_ANDROID_) +#define FXSYS_nan() NAN +#endif +enum BCFORMAT { + BCFORMAT_UNSPECIFY = -1, + BCFORMAT_CODABAR, + BCFORMAT_CODE_39, + BCFORMAT_CODE_128, + BCFORMAT_CODE_128B, + BCFORMAT_CODE_128C, + BCFORMAT_EAN_8, + BCFORMAT_UPC_A, + BCFORMAT_EAN_13, + BCFORMAT_PDF_417, + BCFORMAT_DATAMATRIX, + BCFORMAT_QR_CODE +}; +#define BCFORMAT_ECLEVEL_L 0 +#define BCFORMAT_ECLEVEL_M 1 +#define BCFORMAT_ECLEVEL_Q 2 +#define BCFORMAT_ECLEVEL_H 3 +#include <ctype.h> +#define FXSYS_IntMax INT_MAX +#define FXSYS_Isdigit isdigit +#define BCExceptionNO 0 +#define BCExceptionNotFound 1 +#define BCExceptionEndLessThanStart 2 +#define BCExceptionUnknownDecoder 3 +#define BCExceptionRotateNotSupported 4 +#define BCExceptionHeightAndWidthMustBeAtLeast1 5 +#define BCExceptionRegionMustFitInsideMatrix 6 +#define BCExceptionCanNotCallGetDimensionOnNonSquareMatrix 7 +#define BCExceptionFormatException 8 +#define BCExceptionIllegalArgumentMustMatchVersionSize 9 +#define BCExceptionChecksumException 10 +#define BCExceptionIllegalArgumentInvalidFirstDigit 11 +#define BCExceptionIllegalArgumentInvalidSecondDigit 12 +#define BCExceptionRuntimeDecodingInvalidISO_IEC 13 +#define BCExceptionRuntimeDecodingInvalidAlphanumeric 14 +#define BCExceptionLeftAndTopMustBeNonnegative 15 +#define BCExceptionIllegalArgument 16 +#define BCExceptionBadECI 17 +#define BCExceptionUnSupportedBarcode 18 +#define BCExceptionUnSupportedString 19 +#define BCExceptionDigitLengthMustBe8 20 +#define BCExceptionDataCheckException 21 +#define BCExceptionExtractNumberValueFromBitArray 22 +#define BCExceptionRead 23 +#define BCExceptionRequestedRowIsOutSizeTheImage 24 +#define BCExceptionNoContents 26 +#define BCExceptionUnSupportEclevel 27 +#define BCExceptionUnSupportMode 28 +#define BCExceptionReferenceMustBeBetween0And7 29 +#define BCExceptionBadErrorLocation 30 +#define BCExceptionDegreeIsNegative 31 +#define BCExceptionDivideByZero 32 +#define BCExceptionCoefficientsSizeIsNull 33 +#define BCExceptionNoCorrectionBytes 34 +#define BCExceptionNoDataBytesProvided 35 +#define BCExceptionR_I_1IsZero 36 +#define BCExceptionAIsZero 37 +#define BCExceptionIsZero 38 +#define BCExceptionDegreeNotMatchRoots 39 +#define BCExceptionContentsLengthShouldBetween1and80 40 +#define BCExceptionOnlyEncodeCODE_128 41 +#define BCExceptionOnlyEncodeCODE_39 42 +#define BCExceptionOnlyEncodeEAN_13 43 +#define BCExceptionOnlyEncodeEAN_8 44 +#define BCExceptionOnlyEncodeITF 45 +#define BCExceptionDigitLengthShould13 46 +#define BCExceptionDigitLengthMustBe6or8or10or12or14or16or20or24or44 47 +#define BCExceptionOnlyEncodeUPC_A 48 +#define BCExceptionDigitLengthShouldBe12 49 +#define BCExceptionValueMustBeEither0or1 50 +#define BCExceptionReedsolomnDecodeException 51 +#define BCExceptionBadIndexException 52 +#define BCExceptionBadValueException 53 +#define BCExceptionBadNumBitsException 54 +#define BCExceptioncanNotOperatexorOperator 55 +#define BCExceptionVersionMust1_40 56 +#define BCExceptionUnknown 57 +#define BCExceptionNoSuchVersion 58 +#define BCExceptionCannotFindBlockInfo 59 +#define BCExceptionDataTooBig 60 +#define BCExceptionInvalidQRCode 61 +#define BCExceptionDataTooMany 62 +#define BCExceptionBitsNotEqualCacity 63 +#define BCExceptionUnsupportedMode 64 +#define BCExceptionInvalidateCharacter 65 +#define BCExceptionBytesNotMatchOffset 66 +#define BCExceptionSizeInBytesDiffer 67 +#define BCExceptionInvalidateMaskPattern 68 +#define BCExceptionNullPointer 69 +#define BCExceptionBadMask 70 +#define BCExceptionBitSizeNot15 71 +#define BCExceptionBitSizeNot18 72 +#define BCExceptionInvalidateImageData 73 +#define BCExceptionHeight_8BeZero 74 +#define BCExceptionCharacterNotThisMode 75 +#define BCExceptionBitsBytesNotMatch 76 +#define BCExceptionInvalidateData 77 +#define BCExceptionLoadFile 78 +#define BCExceptionPDF417EncodeFail 79 +#define BCExceptionFailToCreateBitmap 80 +#define BCExceptionLoadFontFail 81 +#define BCExceptionOnlyEncodeCODEBAR 82 +#define BCExceptionCodabarShouldStartWithOneOfABCD 83 +#define BCExceptionCodabarShouldEndWithOneOfTNE 84 +#define BCExceptionCodabarEncodeCharsInvalid 85 +#define BCExceptionOnlyEncodeDATAMATRIX 86 +#define BCExceptionCharactersOutsideISO88591Encoding 87 +#define BCExceptionIllegalDataCodewords 88 +#define BCExceptionCannotHandleThisNumberOfDataRegions 89 +#define BCExceptionIllegalStateUnexpectedCase 90 +#define BCExceptionIllegalStateCountMustNotExceed4 91 +#define BCExceptionIllegalStateMessageLengthInvalid 92 +#define BCExceptionIllegalArgumentNotGigits 93 +#define BCExceptionIllegalStateIllegalMode 94 +#define BCExceptionOnlyEncodePDF417 95 +#define BCExceptionNonEncodableCharacterDetected 96 +#define BCExceptionErrorCorrectionLevelMustBeBetween0And8 97 +#define BCExceptionNoRecommendationPossible 98 +#define BCExceptionIllegalArgumentnMustBeAbove0 99 +#define BCExceptionUnableToFitMessageInColumns 100 +#define BCExceptionEncodedMessageContainsTooManyCodeWords 101 +#define BCExceptionBitmapSizeError 102 +#define BCExceptionFormatInstance 102 +#define BCExceptionChecksumInstance 103 +#define BCExceptiontNotFoundInstance 104 +#define BCExceptionNotFoundInstance 105 +#define BCExceptionCannotMetadata 106 +#define TWO_DIGIT_DATA_LENGTH_SIZE 24 +#define THREE_DIGIT_DATA_LENGTH_SIZE 23 +#define THREE_DIGIT_PLUS_DIGIT_DATA_LENGTH_SIZE 57 +#define FOUR_DIGIT_DATA_LENGTH_SIZE 17 +#define BC_EXCEPTION_CHECK_ReturnVoid(e) \ + if (e != BCExceptionNO) \ + return; +#define BC_EXCEPTION_CHECK_ReturnValue(e, v) \ + if (e != BCExceptionNO) \ + return v; + +#endif // XFA_FXBARCODE_UTILS_H_ |