// 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 "barcode.h"
#include "BC_Reader.h"
#include "BC_Writer.h"
#include "BC_DecoderResult.h"
#include "BC_LuminanceSource.h"
#include "BC_BufferedImageLuminanceSource.h"
#include "BC_Binarizer.h"
#include "BC_BinaryBitmap.h"
#include "BC_UtilCodingConvert.h"
#include "BC_ResultPoint.h"
#include "BC_BinaryBitmap.h"
#include "BC_TwoDimWriter.h"
#include "common/BC_GlobalHistogramBinarizer.h"
#include "common/BC_CommonBitMatrix.h"
#include "common/BC_CommonBitArray.h"
#include "common/BC_CommonBitMatrix.h"
#include "common/BC_CommonDecoderResult.h"
#include "datamatrix/BC_DataMatrixReader.h"
#include "datamatrix/BC_DataMatrixWriter.h"
#include "oned/BC_OneDReader.h"
#include "oned/BC_OneDimReader.h"
#include "oned/BC_OneDimWriter.h"
#include "oned/BC_OnedCode39Reader.h"
#include "oned/BC_OnedCode39Writer.h"
#include "oned/BC_OnedCodaBarReader.h"
#include "oned/BC_OnedCodaBarWriter.h"
#include "oned/BC_OnedCode128Reader.h"
#include "oned/BC_OnedCode128Writer.h"
#include "oned/BC_OnedEAN8Reader.h"
#include "oned/BC_OnedEAN8Writer.h"
#include "oned/BC_OnedEAN13Reader.h"
#include "oned/BC_OnedEAN13Writer.h"
#include "oned/BC_OnedUPCAReader.h"
#include "oned/BC_OnedUPCAWriter.h"
#include "pdf417/BC_PDF417DetectorResult.h"
#include "pdf417/BC_PDF417Compaction.h"
#include "pdf417/BC_PDF417.h"
#include "pdf417/BC_PDF417Writer.h"
#include "pdf417/BC_PDF417Detector.h"
#include "pdf417/BC_PDF417DetectorResult.h"
#include "pdf417/BC_PDF417Codeword.h"
#include "pdf417/BC_PDF417Common.h"
#include "pdf417/BC_PDF417BarcodeValue.h"
#include "pdf417/BC_PDF417BarcodeMetadata.h"
#include "pdf417/BC_PDF417BoundingBox.h"
#include "pdf417/BC_PDF417DetectionResultColumn.h"
#include "pdf417/BC_PDF417DetectionResultRowIndicatorColumn.h"
#include "pdf417/BC_PDF417DetectionResult.h"
#include "pdf417/BC_PDF417DecodedBitStreamParser.h"
#include "pdf417/BC_PDF417CodewordDecoder.h"
#include "pdf417/BC_PDF417DecodedBitStreamParser.h"
#include "pdf417/BC_PDF417ECModulusPoly.h"
#include "pdf417/BC_PDF417ECModulusGF.h"
#include "pdf417/BC_PDF417ECErrorCorrection.h"
#include "pdf417/BC_PDF417DecodedBitStreamParser.h"
#include "pdf417/BC_PDF417ScanningDecoder.h"
#include "pdf417/BC_PDF417Reader.h"
#include "pdf417/BC_PDF417HighLevelEncoder.h"
#include "qrcode/BC_QRCodeReader.h"
#include "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*) FX_NEW (CBC_OnedCode39Reader);
    m_pBCWriter = (CBC_Writer*) FX_NEW (CBC_OnedCode39Writer);
}
CBC_Code39::CBC_Code39(FX_BOOL usingCheckDigit)
{
    m_pBCReader = (CBC_Reader*) FX_NEW CBC_OnedCode39Reader(usingCheckDigit);
    m_pBCWriter = (CBC_Writer*) FX_NEW CBC_OnedCode39Writer;
}
CBC_Code39::CBC_Code39(FX_BOOL usingCheckDigit, FX_BOOL extendedMode)
{
    m_pBCReader = (CBC_Reader*) FX_NEW CBC_OnedCode39Reader(usingCheckDigit, extendedMode);
    m_pBCWriter = (CBC_Writer*) FX_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 = 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*) FX_NEW (CBC_OnedCodaBarReader);
    m_pBCWriter = (CBC_Writer*) FX_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 = 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 *) FX_NEW (CBC_OnedCode128Reader);
    m_pBCWriter = (CBC_Writer *) FX_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 = 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*) FX_NEW (CBC_OnedEAN8Reader);
    m_pBCWriter = (CBC_Writer*) FX_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 = 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*) FX_NEW (CBC_OnedEAN13Reader);
    m_pBCWriter = (CBC_Writer*) FX_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 = 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*) FX_NEW (CBC_OnedUPCAReader);
    ((CBC_OnedUPCAReader *)m_pBCReader)->Init();
    m_pBCWriter = (CBC_Writer*) FX_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 = 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 *) FX_NEW (CBC_QRCodeReader);
    ((CBC_QRCodeReader*)m_pBCReader)->Init();
    m_pBCWriter = (CBC_Writer *) FX_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*) FX_NEW (CBC_PDF417Reader);
    m_pBCWriter = (CBC_Writer*) FX_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)
{
    BCFORMAT format	= BCFORMAT_PDF_417;
    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*) FX_NEW (CBC_DataMatrixReader);
    ((CBC_DataMatrixReader*)m_pBCReader)->Init();
    m_pBCWriter = (CBC_Writer*) FX_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());
}
