bug fixing at qr code encoding. this tests fail

This commit is contained in:
favoritas37 2015-10-31 19:14:59 +02:00
parent 4ad07d7cb3
commit 630f560e89
9 changed files with 53 additions and 36 deletions

View File

@ -30,6 +30,10 @@ Rectangle {
anchors.right: parent.right anchors.right: parent.right
anchors.margins: 10 anchors.margins: 10
title: "Result barcode image" title: "Result barcode image"
Image{
id:resultImage
}
} }
QZXing { QZXing {

View File

@ -42,3 +42,4 @@ void ImageHandler::save(QObject *imageObj, const QString &path,
QImage img = extractQImage(imageObj, offsetX, offsetY, width, height); QImage img = extractQImage(imageObj, offsetX, offsetY, width, height);
img.save(path); img.save(path);
} }

View File

@ -295,6 +295,9 @@ QImage QZXing::encodeData(const QString& data)
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] ? 0 : 255);
image.save("C:\\tmp.png");
return image; return image;
} }

View File

@ -41,6 +41,7 @@ private:
public: public:
Mode(const Mode& mode); Mode(const Mode& mode);
Mode();
static Mode TERMINATOR; static Mode TERMINATOR;
static Mode NUMERIC; static Mode NUMERIC;

View File

@ -43,6 +43,14 @@ Mode Mode::FNC1_FIRST_POSITION(0, 0, 0, 0x05, "FNC1_FIRST_POSITION");
Mode Mode::FNC1_SECOND_POSITION(0, 0, 0, 0x09, "FNC1_SECOND_POSITION"); Mode Mode::FNC1_SECOND_POSITION(0, 0, 0, 0x09, "FNC1_SECOND_POSITION");
Mode Mode::HANZI(8, 10, 12, 0x0D, "HANZI"); Mode Mode::HANZI(8, 10, 12, 0x0D, "HANZI");
Mode::Mode() :
characterCountBitsForVersions0To9_(0),
characterCountBitsForVersions10To26_(0),
characterCountBitsForVersions27AndHigher_(0),
bits_(0),
name_("")
{}
Mode::Mode(int cbv0_9, int cbv10_26, int cbv27, int bits, char const* name) : Mode::Mode(int cbv0_9, int cbv10_26, int cbv27, int bits, char const* name) :
characterCountBitsForVersions0To9_(cbv0_9), characterCountBitsForVersions10To26_(cbv10_26), characterCountBitsForVersions0To9_(cbv0_9), characterCountBitsForVersions10To26_(cbv10_26),
characterCountBitsForVersions27AndHigher_(cbv27), bits_(bits), name_(name) characterCountBitsForVersions27AndHigher_(cbv27), bits_(bits), name_(name)

View File

@ -48,14 +48,14 @@ public:
*/ */
static int getAlphanumericCode(int code); static int getAlphanumericCode(int code);
static Mode* chooseMode(const QString& content); static Mode chooseMode(const QString& content);
/** /**
* Choose the best mode by examining the content. Note that 'encoding' is used as a hint; * Choose the best mode by examining the content. Note that 'encoding' is used as a hint;
* if it is Shift_JIS, and the input is only double-byte Kanji, then we return {@link Mode#KANJI}. * if it is Shift_JIS, and the input is only double-byte Kanji, then we return {@link Mode#KANJI}.
*/ */
private: private:
static Mode* chooseMode(const QString& content, const QString& encoding); static Mode chooseMode(const QString& content, const QString& encoding);
//static bool isOnlyDoubleByteKanji(const QString& content); //static bool isOnlyDoubleByteKanji(const QString& content);

View File

@ -6,7 +6,7 @@ namespace zxing {
namespace qrcode { namespace qrcode {
QRCode::QRCode() : QRCode::QRCode() :
mode_ptr_(NULL), mode_(),
ecLevel_ptr_(NULL), ecLevel_ptr_(NULL),
version_ptr_(NULL), version_ptr_(NULL),
maskPattern_(-1), maskPattern_(-1),
@ -14,22 +14,22 @@ QRCode::QRCode() :
QRCode::~QRCode() QRCode::~QRCode()
{ {
if(mode_ptr_) // if(mode_ptr_)
delete mode_ptr_; // delete mode_ptr_;
if(ecLevel_ptr_) // if(ecLevel_ptr_)
delete ecLevel_ptr_; // delete ecLevel_ptr_;
if(version_ptr_) // if(version_ptr_)
delete version_ptr_; // delete version_ptr_;
if(matrix_ptr_) // if(matrix_ptr_)
delete matrix_ptr_; // delete matrix_ptr_;
} }
Ref<Mode> QRCode::getMode() const Mode QRCode::getMode() const
{ {
return mode_ptr_; return mode_;
} }
Ref<ErrorCorrectionLevel> QRCode::getECLevel() const Ref<ErrorCorrectionLevel> QRCode::getECLevel() const
@ -56,8 +56,8 @@ const std::string QRCode::toString()
{ {
std::stringstream result; std::stringstream result;
result << "<<\n"; result << "<<\n";
result << " mode: {unimpl}"; // result << " mode: {unimpl}";
result << mode_ptr_; // result << mode_;
result << "\n ecLevel: {unimpl}"; result << "\n ecLevel: {unimpl}";
//result << ecLevel_; //result << ecLevel_;
result << "\n version: "; result << "\n version: ";
@ -74,9 +74,9 @@ const std::string QRCode::toString()
return result.str(); return result.str();
} }
void QRCode::setMode(Ref<Mode> value) void QRCode::setMode(const Mode& value)
{ {
mode_ptr_ = value; mode_ = value;
} }
void QRCode::setECLevel(Ref<ErrorCorrectionLevel> value) void QRCode::setECLevel(Ref<ErrorCorrectionLevel> value)

View File

@ -15,7 +15,7 @@ class QRCode : public Counted
{ {
private: private:
Ref<Mode> mode_ptr_; Mode mode_;
Ref<ErrorCorrectionLevel> ecLevel_ptr_; Ref<ErrorCorrectionLevel> ecLevel_ptr_;
Ref<Version> version_ptr_; Ref<Version> version_ptr_;
int maskPattern_; int maskPattern_;
@ -26,13 +26,13 @@ public:
QRCode(); QRCode();
~QRCode(); ~QRCode();
Ref<Mode> getMode() const; Mode getMode() const;
Ref<ErrorCorrectionLevel> getECLevel() const; Ref<ErrorCorrectionLevel> getECLevel() const;
Ref<Version> getVersion() const; Ref<Version> getVersion() const;
int getMaskPattern() const; int getMaskPattern() const;
Ref<ByteMatrix> getMatrix() const; Ref<ByteMatrix> getMatrix() const;
const std::string toString(); const std::string toString();
void setMode(Ref<Mode> value); void setMode(const Mode &value);
void setECLevel(Ref<ErrorCorrectionLevel> value); void setECLevel(Ref<ErrorCorrectionLevel> value);
void setVersion(Ref<Version> version); void setVersion(Ref<Version> version);
void setMaskPattern(int value); void setMaskPattern(int value);

View File

@ -50,14 +50,14 @@ Ref<QRCode> Encoder::encode(const QString& content, ErrorCorrectionLevel &ecLeve
// Pick an encoding mode appropriate for the content. Note that this will not attempt to use // Pick an encoding mode appropriate for the content. Note that this will not attempt to use
// multiple modes / segments even if that were more efficient. Twould be nice. // multiple modes / segments even if that were more efficient. Twould be nice.
Mode* mode = chooseMode(content, encoding); Mode mode = chooseMode(content, encoding);
// This will store the header information, like mode and // This will store the header information, like mode and
// length, as well as "header" segments like an ECI segment. // length, as well as "header" segments like an ECI segment.
BitArray headerBits; BitArray headerBits;
// Append ECI segment if applicable // Append ECI segment if applicable
if (mode == &Mode::BYTE && DEFAULT_BYTE_MODE_ENCODING != encoding) { if (mode == Mode::BYTE && DEFAULT_BYTE_MODE_ENCODING != encoding) {
zxing::common::CharacterSetECI* eci = zxing::common::CharacterSetECI* eci =
zxing::common::CharacterSetECI::getCharacterSetECIByName(encoding.toStdString().c_str()); zxing::common::CharacterSetECI::getCharacterSetECIByName(encoding.toStdString().c_str());
if (eci != NULL) { if (eci != NULL) {
@ -66,34 +66,34 @@ Ref<QRCode> Encoder::encode(const QString& content, ErrorCorrectionLevel &ecLeve
} }
// (With ECI in place,) Write the mode marker // (With ECI in place,) Write the mode marker
appendModeInfo(*mode, headerBits); appendModeInfo(mode, headerBits);
// Collect data within the main segment, separately, to count its size if needed. Don't add it to // Collect data within the main segment, separately, to count its size if needed. Don't add it to
// main payload yet. // main payload yet.
BitArray dataBits; BitArray dataBits;
appendBytes(content, *mode, dataBits, encoding); appendBytes(content, mode, dataBits, encoding);
// Hard part: need to know version to know how many bits length takes. But need to know how many // Hard part: need to know version to know how many bits length takes. But need to know how many
// bits it takes to know version. First we take a guess at version by assuming version will be // bits it takes to know version. First we take a guess at version by assuming version will be
// the minimum, 1: // the minimum, 1:
int provisionalBitsNeeded = headerBits.getSize() int provisionalBitsNeeded = headerBits.getSize()
+ mode->getCharacterCountBits(Version::getVersionForNumber(1)) + mode.getCharacterCountBits(Version::getVersionForNumber(1))
+ dataBits.getSize(); + dataBits.getSize();
Ref<Version> provisionalVersion = chooseVersion(provisionalBitsNeeded, ecLevel); Ref<Version> provisionalVersion = chooseVersion(provisionalBitsNeeded, ecLevel);
// Use that guess to calculate the right version. I am still not sure this works in 100% of cases. // Use that guess to calculate the right version. I am still not sure this works in 100% of cases.
int bitsNeeded = headerBits.getSize() int bitsNeeded = headerBits.getSize()
+ mode->getCharacterCountBits(provisionalVersion) + mode.getCharacterCountBits(provisionalVersion)
+ dataBits.getSize(); + dataBits.getSize();
Ref<Version> version = chooseVersion(bitsNeeded, ecLevel); Ref<Version> version = chooseVersion(bitsNeeded, ecLevel);
BitArray headerAndDataBits; BitArray headerAndDataBits;
headerAndDataBits.appendBitArray(headerBits); headerAndDataBits.appendBitArray(headerBits);
// Find "length" of main segment and write it // Find "length" of main segment and write it
int numLetters = (*mode == Mode::BYTE) ? dataBits.getSizeInBytes() : content.length(); int numLetters = (mode == Mode::BYTE) ? dataBits.getSizeInBytes() : content.length();
appendLengthInfo(numLetters, *version, *mode, headerAndDataBits); appendLengthInfo(numLetters, *version, mode, headerAndDataBits);
// Put data together into the overall payload // Put data together into the overall payload
headerAndDataBits.appendBitArray(dataBits); headerAndDataBits.appendBitArray(dataBits);
@ -112,7 +112,7 @@ Ref<QRCode> Encoder::encode(const QString& content, ErrorCorrectionLevel &ecLeve
Ref<QRCode> qrCode(new QRCode); Ref<QRCode> qrCode(new QRCode);
qrCode->setECLevel(Ref<ErrorCorrectionLevel>(&ecLevel)); qrCode->setECLevel(Ref<ErrorCorrectionLevel>(&ecLevel));
qrCode->setMode(Ref<Mode>(mode)); qrCode->setMode(mode);
qrCode->setVersion(version); qrCode->setVersion(version);
// Choose the mask pattern and set to "qrCode". // Choose the mask pattern and set to "qrCode".
@ -142,7 +142,7 @@ int Encoder::getAlphanumericCode(int code)
return -1; return -1;
} }
Mode* Encoder::chooseMode(const QString& content) Mode Encoder::chooseMode(const QString& content)
{ {
return chooseMode(content, ""); return chooseMode(content, "");
} }
@ -151,10 +151,10 @@ Mode* Encoder::chooseMode(const QString& content)
* Choose the best mode by examining the content. Note that 'encoding' is used as a hint; * Choose the best mode by examining the content. Note that 'encoding' is used as a hint;
* if it is Shift_JIS, and the input is only double-byte Kanji, then we return {@link Mode#KANJI}. * if it is Shift_JIS, and the input is only double-byte Kanji, then we return {@link Mode#KANJI}.
*/ */
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")
return &(Mode::BYTE); return Mode::BYTE;
bool hasNumeric = false; bool hasNumeric = false;
bool hasAlphanumeric = false; bool hasAlphanumeric = false;
@ -165,16 +165,16 @@ Mode* Encoder::chooseMode(const QString& content, const QString& encoding)
} else if (getAlphanumericCode(c) != -1) { } else if (getAlphanumericCode(c) != -1) {
hasAlphanumeric = true; hasAlphanumeric = true;
} else { } else {
return &Mode::BYTE; return Mode::BYTE;
} }
} }
if (hasAlphanumeric) { if (hasAlphanumeric) {
return &Mode::ALPHANUMERIC; return Mode::ALPHANUMERIC;
} }
if (hasNumeric) { if (hasNumeric) {
return &Mode::NUMERIC; return Mode::NUMERIC;
} }
return &Mode::BYTE; return Mode::BYTE;
} }
//bool Encoder::isOnlyDoubleByteKanji(const QString& content) //bool Encoder::isOnlyDoubleByteKanji(const QString& content)