bug fixing in the decoder side

This commit is contained in:
favoritas37 2015-11-22 20:33:49 +02:00
parent 630f560e89
commit 09c7d0c2c8
6 changed files with 40 additions and 38 deletions

View File

@ -11,6 +11,7 @@
#include <QUrl> #include <QUrl>
#include <zxing/qrcode/encoder/Encoder.h> #include <zxing/qrcode/encoder/Encoder.h>
#include <zxing/qrcode/ErrorCorrectionLevel.h> #include <zxing/qrcode/ErrorCorrectionLevel.h>
#include <QColor>
using namespace zxing; using namespace zxing;
@ -288,15 +289,23 @@ QString QZXing::decodeSubImageQML(const QUrl &imageUrl,
QImage QZXing::encodeData(const QString& data) QImage QZXing::encodeData(const QString& data)
{ {
QImage image;
try {
Ref<qrcode::QRCode> barcode = qrcode::Encoder::encode(data, qrcode::ErrorCorrectionLevel::L ); Ref<qrcode::QRCode> barcode = qrcode::Encoder::encode(data, qrcode::ErrorCorrectionLevel::L );
Ref<qrcode::ByteMatrix> bytesRef = barcode->getMatrix(); Ref<qrcode::ByteMatrix> bytesRef = barcode->getMatrix();
const std::vector< std::vector <char> >& bytes = bytesRef->getArray(); const std::vector< std::vector <char> >& bytes = bytesRef->getArray();
QImage image(bytesRef->getWidth(), bytesRef->getHeight(), QImage::Format_ARGB32); QImage image(bytesRef->getWidth(), bytesRef->getHeight(), QImage::Format_ARGB32);
for(int i=0; i<bytesRef->getWidth(); i++) for(int i=0; i<bytesRef->getWidth(); i++)
for(int j=0; j<bytesRef->getHeight(); j++) for(int j=0; j<bytesRef->getHeight(); j++)
image.setPixel(i,j,bytes[i][j] ? 0 : 255); image.setPixel(i, j, bytes[i][j] ?
qRgb(0,0,0) :
qRgb(255,255,255));
image.save("C:\\tmp.png"); image = image.scaled(240, 240);
bool success = image.save("tmp.bmp","BMP");
} catch (std::exception& e) {
std::cout << "Error: " << e.what() << std::endl;
}
return image; return image;
} }

View File

@ -46,7 +46,7 @@ void ReedSolomonEncoder::encode(std::vector<int> &toEncode, int ecBytes)
ArrayRef<int> infoCoefficients(dataBytes); ArrayRef<int> infoCoefficients(dataBytes);
//memcpy(infoCoefficients.operator ->(), toEncode.data(), dataBytes); //memcpy(infoCoefficients.operator ->(), toEncode.data(), dataBytes);
//to-do optimize the following loop //to-do optimize the following loop
for(int i=0; i< dataBytes; ++i) for(int i=0; i< dataBytes; i++)
infoCoefficients[i] = toEncode[i]; infoCoefficients[i] = toEncode[i];
Ref<GenericGFPoly> info(new GenericGFPoly(field_, infoCoefficients)); Ref<GenericGFPoly> info(new GenericGFPoly(field_, infoCoefficients));

View File

@ -49,8 +49,8 @@ void ByteMatrix::set(size_t x, size_t y, bool value)
void ByteMatrix::clear(const char value) void ByteMatrix::clear(const char value)
{ {
for (size_t y = 0; y < height_; ++y) { for (size_t y = 0; y < height_; y++) {
for (size_t x = 0; x < width_; ++x) { for (size_t x = 0; x < width_; x++) {
bytes_[y][x] = value; bytes_[y][x] = value;
} }
} }
@ -59,8 +59,8 @@ void ByteMatrix::clear(const char value)
const std::string ByteMatrix::toString() const const std::string ByteMatrix::toString() const
{ {
std::stringstream result;// = new StringBuilder(2 * width * height + 2); std::stringstream result;// = new StringBuilder(2 * width * height + 2);
for (size_t y = 0; y < height_; ++y) { for (size_t y = 0; y < height_; y++) {
for (size_t x = 0; x < width_; ++x) { for (size_t x = 0; x < width_; x++) {
switch (bytes_[y][x]) { switch (bytes_[y][x]) {
case 0: case 0:
result << " 0"; result << " 0";

View File

@ -226,7 +226,7 @@ int MatrixUtil::findMSBSet(int value)
{ {
int numDigits = 0; int numDigits = 0;
while (value != 0) { while (value != 0) {
value >>= 1; value = ((unsigned int)value) >> (unsigned int)1;
++numDigits; ++numDigits;
} }
return numDigits; return numDigits;

View File

@ -14,17 +14,6 @@ QRCode::QRCode() :
QRCode::~QRCode() QRCode::~QRCode()
{ {
// if(mode_ptr_)
// delete mode_ptr_;
// if(ecLevel_ptr_)
// delete ecLevel_ptr_;
// if(version_ptr_)
// delete version_ptr_;
// if(matrix_ptr_)
// delete matrix_ptr_;
} }
Mode QRCode::getMode() const Mode QRCode::getMode() const

View File

@ -107,7 +107,7 @@ Ref<QRCode> Encoder::encode(const QString& content, ErrorCorrectionLevel &ecLeve
Ref<BitArray> finalBits(interleaveWithECBytes(headerAndDataBits, Ref<BitArray> finalBits(interleaveWithECBytes(headerAndDataBits,
version->getTotalCodewords(), version->getTotalCodewords(),
numDataBytes, numDataBytes,
1));//ecBlocks->getNumBlocks()); ecBlocks.getECBlocks().size()));
Ref<QRCode> qrCode(new QRCode); Ref<QRCode> qrCode(new QRCode);
@ -154,11 +154,14 @@ Mode Encoder::chooseMode(const QString& content)
Mode Encoder::chooseMode(const QString& content, const QString& encoding) Mode Encoder::chooseMode(const QString& content, const QString& encoding)
{ {
if (encoding == "Shift_JIS") if (encoding == "Shift_JIS")
{
std::cout << "DEBUG: Shift_JIS detected...be aware!" << std::endl;
return Mode::BYTE; return Mode::BYTE;
}
bool hasNumeric = false; bool hasNumeric = false;
bool hasAlphanumeric = false; bool hasAlphanumeric = false;
for (int i = 0; i < content.size(); ++i) { for (int i = 0; i < content.size(); i++) {
char c = content.at(i).toLatin1(); char c = content.at(i).toLatin1();
if (c >= '0' && c <= '9') { if (c >= '0' && c <= '9') {
hasNumeric = true; hasNumeric = true;
@ -256,7 +259,7 @@ void Encoder::terminateBits(int numDataBytes, BitArray& bits)
} }
// Append termination bits. See 8.4.8 of JISX0510:2004 (p.24) for details. // Append termination bits. See 8.4.8 of JISX0510:2004 (p.24) for details.
// If the last byte isn't 8-bit aligned, we'll add padding bits. // If the last byte isn't 8-bit aligned, we'll add padding bits.
int numBitsInLastByte = bits.getSize() % 8; int numBitsInLastByte = bits.getSize() & 7;//% 8;
if (numBitsInLastByte > 0) { if (numBitsInLastByte > 0) {
for (int i = numBitsInLastByte; i < 8; i++) { for (int i = numBitsInLastByte; i < 8; i++) {
bits.appendBit(false); bits.appendBit(false);
@ -265,7 +268,7 @@ void Encoder::terminateBits(int numDataBytes, BitArray& bits)
// If we have more space, we'll fill the space with padding patterns defined in 8.4.9 (p.24). // If we have more space, we'll fill the space with padding patterns defined in 8.4.9 (p.24).
int bitSizeInBytes = bits.getSizeInBytes(); int bitSizeInBytes = bits.getSizeInBytes();
int numPaddingBytes = numDataBytes - bitSizeInBytes; int numPaddingBytes = numDataBytes - bitSizeInBytes;
for (int i = 0; i < numPaddingBytes; ++i) { for (int i = 0; i < numPaddingBytes; i++) {
bits.appendBits((i & 0x01) == 0 ? 0xEC : 0x11, 8); bits.appendBits((i & 0x01) == 0 ? 0xEC : 0x11, 8);
} }
if (bits.getSize() != capacity) { if (bits.getSize() != capacity) {
@ -358,9 +361,9 @@ BitArray* Encoder::interleaveWithECBytes(const BitArray& bits,
int maxNumEcBytes = 0; int maxNumEcBytes = 0;
// Since, we know the number of reedsolmon blocks, we can initialize the vector with the number. // Since, we know the number of reedsolmon blocks, we can initialize the vector with the number.
QList< BlockPair > blocks; std::vector< BlockPair > blocks;
for (int i = 0; i < numRSBlocks; ++i) { for (int i = 0; i < numRSBlocks; i++) {
std::vector<int> numDataBytesInBlock; std::vector<int> numDataBytesInBlock;
std::vector<int> numEcBytesInBlock; std::vector<int> numEcBytesInBlock;
getNumDataBytesAndNumECBytesForBlockID( getNumDataBytesAndNumECBytesForBlockID(
@ -385,8 +388,8 @@ BitArray* Encoder::interleaveWithECBytes(const BitArray& bits,
BitArray* result = new BitArray; BitArray* result = new BitArray;
// First, place data blocks. // First, place data blocks.
for (int i = 0; i < maxNumDataBytes; ++i) { for (int i = 0; i < maxNumDataBytes; i++) {
for (QList< BlockPair >::iterator it=blocks.begin(); it != blocks.end(); ++it) { for (std::vector< BlockPair >::iterator it=blocks.begin(); it != blocks.end(); it++) {
ArrayRef<char> dataBytes = it->getDataBytes(); ArrayRef<char> dataBytes = it->getDataBytes();
if (i < dataBytes.array_->size()) { if (i < dataBytes.array_->size()) {
result->appendBits(dataBytes[i], 8); ///????? are we sure? result->appendBits(dataBytes[i], 8); ///????? are we sure?
@ -394,8 +397,8 @@ BitArray* Encoder::interleaveWithECBytes(const BitArray& bits,
} }
} }
// Then, place error correction blocks. // Then, place error correction blocks.
for (int i = 0; i < maxNumEcBytes; ++i) { for (int i = 0; i < maxNumEcBytes; i++) {
for (QList< BlockPair >::iterator it=blocks.begin(); it != blocks.end(); ++it) { for (std::vector< BlockPair >::iterator it=blocks.begin(); it != blocks.end(); it++) {
ArrayRef<char> ecBytes = it->getErrorCorrectionBytes(); ArrayRef<char> ecBytes = it->getErrorCorrectionBytes();
if (i < ecBytes.array_->size()) { if (i < ecBytes.array_->size()) {
result->appendBits(ecBytes[i], 8); result->appendBits(ecBytes[i], 8);
@ -418,8 +421,9 @@ ArrayRef<char> Encoder::generateECBytes(const std::vector<char>& dataBytes, int
{ {
int numDataBytes = dataBytes.size(); int numDataBytes = dataBytes.size();
std::vector<int> toEncode; std::vector<int> toEncode;
toEncode.resize(numDataBytes + numEcBytesInBlock);
for (int i = 0; i < numDataBytes; i++) for (int i = 0; i < numDataBytes; i++)
toEncode.push_back(dataBytes[i] & 0xFF); toEncode[i] = dataBytes[i] & 0xFF;
zxing::ReedSolomonEncoder encoder(GenericGF::QR_CODE_FIELD_256); zxing::ReedSolomonEncoder encoder(GenericGF::QR_CODE_FIELD_256);
encoder.encode(toEncode, numEcBytesInBlock); encoder.encode(toEncode, numEcBytesInBlock);
@ -540,7 +544,7 @@ void Encoder::append8BitBytes(const QString& content, BitArray& bits, const QStr
// throw new WriterException(uee); // throw new WriterException(uee);
// } // }
for (int i=0; i<content.size(); ++i) { for (int i=0; i<content.size(); i++) {
bits.appendBits(content.at(i).toLatin1(), 8); bits.appendBits(content.at(i).toLatin1(), 8);
} }
} }