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.margins: 10
title: "Result barcode image"
Image{
id:resultImage
}
}
QZXing {

View File

@ -42,3 +42,4 @@ void ImageHandler::save(QObject *imageObj, const QString &path,
QImage img = extractQImage(imageObj, offsetX, offsetY, width, height);
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 j=0; j<bytesRef->getHeight(); j++)
image.setPixel(i,j,bytes[i][j] ? 0 : 255);
image.save("C:\\tmp.png");
return image;
}

View File

@ -41,6 +41,7 @@ private:
public:
Mode(const Mode& mode);
Mode();
static Mode TERMINATOR;
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::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) :
characterCountBitsForVersions0To9_(cbv0_9), characterCountBitsForVersions10To26_(cbv10_26),
characterCountBitsForVersions27AndHigher_(cbv27), bits_(bits), name_(name)

View File

@ -48,14 +48,14 @@ public:
*/
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;
* if it is Shift_JIS, and the input is only double-byte Kanji, then we return {@link Mode#KANJI}.
*/
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);

View File

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

View File

@ -15,7 +15,7 @@ class QRCode : public Counted
{
private:
Ref<Mode> mode_ptr_;
Mode mode_;
Ref<ErrorCorrectionLevel> ecLevel_ptr_;
Ref<Version> version_ptr_;
int maskPattern_;
@ -26,13 +26,13 @@ public:
QRCode();
~QRCode();
Ref<Mode> getMode() const;
Mode getMode() const;
Ref<ErrorCorrectionLevel> getECLevel() const;
Ref<Version> getVersion() const;
int getMaskPattern() const;
Ref<ByteMatrix> getMatrix() const;
const std::string toString();
void setMode(Ref<Mode> value);
void setMode(const Mode &value);
void setECLevel(Ref<ErrorCorrectionLevel> value);
void setVersion(Ref<Version> version);
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
// 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
// length, as well as "header" segments like an ECI segment.
BitArray headerBits;
// 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::getCharacterSetECIByName(encoding.toStdString().c_str());
if (eci != NULL) {
@ -66,34 +66,34 @@ Ref<QRCode> Encoder::encode(const QString& content, ErrorCorrectionLevel &ecLeve
}
// (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
// main payload yet.
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
// bits it takes to know version. First we take a guess at version by assuming version will be
// the minimum, 1:
int provisionalBitsNeeded = headerBits.getSize()
+ mode->getCharacterCountBits(Version::getVersionForNumber(1))
+ mode.getCharacterCountBits(Version::getVersionForNumber(1))
+ dataBits.getSize();
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.
int bitsNeeded = headerBits.getSize()
+ mode->getCharacterCountBits(provisionalVersion)
+ mode.getCharacterCountBits(provisionalVersion)
+ dataBits.getSize();
Ref<Version> version = chooseVersion(bitsNeeded, ecLevel);
BitArray headerAndDataBits;
headerAndDataBits.appendBitArray(headerBits);
// Find "length" of main segment and write it
int numLetters = (*mode == Mode::BYTE) ? dataBits.getSizeInBytes() : content.length();
appendLengthInfo(numLetters, *version, *mode, headerAndDataBits);
int numLetters = (mode == Mode::BYTE) ? dataBits.getSizeInBytes() : content.length();
appendLengthInfo(numLetters, *version, mode, headerAndDataBits);
// Put data together into the overall payload
headerAndDataBits.appendBitArray(dataBits);
@ -112,7 +112,7 @@ Ref<QRCode> Encoder::encode(const QString& content, ErrorCorrectionLevel &ecLeve
Ref<QRCode> qrCode(new QRCode);
qrCode->setECLevel(Ref<ErrorCorrectionLevel>(&ecLevel));
qrCode->setMode(Ref<Mode>(mode));
qrCode->setMode(mode);
qrCode->setVersion(version);
// Choose the mask pattern and set to "qrCode".
@ -142,7 +142,7 @@ int Encoder::getAlphanumericCode(int code)
return -1;
}
Mode* Encoder::chooseMode(const QString& content)
Mode Encoder::chooseMode(const QString& 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;
* 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")
return &(Mode::BYTE);
return Mode::BYTE;
bool hasNumeric = false;
bool hasAlphanumeric = false;
@ -165,16 +165,16 @@ Mode* Encoder::chooseMode(const QString& content, const QString& encoding)
} else if (getAlphanumericCode(c) != -1) {
hasAlphanumeric = true;
} else {
return &Mode::BYTE;
return Mode::BYTE;
}
}
if (hasAlphanumeric) {
return &Mode::ALPHANUMERIC;
return Mode::ALPHANUMERIC;
}
if (hasNumeric) {
return &Mode::NUMERIC;
return Mode::NUMERIC;
}
return &Mode::BYTE;
return Mode::BYTE;
}
//bool Encoder::isOnlyDoubleByteKanji(const QString& content)