// 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 "../barcode.h"
#include "../common/BC_CommonBitMatrix.h"
#include "../common/reedsolomon/BC_ReedSolomonDecoder.h"
#include "../common/reedsolomon/BC_ReedSolomonGF256.h"
#include "BC_DataMatrixDecoder.h"
#include "BC_DataMatrixBitMatrixParser.h"
#include "BC_DataMatrixVersion.h"
#include "BC_DataMatrixDataBlock.h"
#include "BC_DataMatrixDecodedBitStreamParser.h"
CBC_DataMatrixDecoder::CBC_DataMatrixDecoder()
{
    m_rsDecoder = NULL;
}
void CBC_DataMatrixDecoder::Init()
{
    m_rsDecoder = FX_NEW CBC_ReedSolomonDecoder(CBC_ReedSolomonGF256::DataMatrixField);
}
CBC_DataMatrixDecoder::~CBC_DataMatrixDecoder()
{
    if(m_rsDecoder != NULL) {
        delete m_rsDecoder;
    }
    m_rsDecoder = NULL;
}
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();
    CFX_ByteArray* byteTemp = parser.ReadCodewords(e);
    BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
    CBC_AutoPtr<CFX_ByteArray> codewords(byteTemp);
    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];
    }
}
