mirror of https://github.com/status-im/qzxing.git
bug fixing in the decoder side
This commit is contained in:
parent
630f560e89
commit
09c7d0c2c8
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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));
|
||||||
|
|
|
@ -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";
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue