mirror of https://github.com/status-im/qzxing.git
bug fixing at qr code encoding. this tests fail
This commit is contained in:
parent
4ad07d7cb3
commit
630f560e89
|
@ -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 {
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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)
|
||||||
|
|
Loading…
Reference in New Issue