mirror of
https://github.com/status-im/qzxing.git
synced 2025-02-18 05:47:03 +00:00
initial implementation of Qr Encoder. Not tested
This commit is contained in:
parent
dbc47abff2
commit
f6c5917c38
@ -23,6 +23,9 @@
|
|||||||
#include "BlockPair.h"
|
#include "BlockPair.h"
|
||||||
#include <QList>
|
#include <QList>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
#include <limits>
|
||||||
|
#include "MatrixUtil.h"
|
||||||
|
#include <string>
|
||||||
|
|
||||||
namespace zxing {
|
namespace zxing {
|
||||||
namespace qrcode {
|
namespace qrcode {
|
||||||
@ -38,7 +41,7 @@ const int Encoder::ALPHANUMERIC_TABLE[Encoder::ALPHANUMERIC_TABLE_SIZE] = {
|
|||||||
25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, -1, -1, -1, -1, -1, // 0x50-0x5f
|
25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, -1, -1, -1, -1, -1, // 0x50-0x5f
|
||||||
};
|
};
|
||||||
|
|
||||||
const QString DEFAULT_BYTE_MODE_ENCODING = "ISO-8859-1";
|
const QString Encoder::DEFAULT_BYTE_MODE_ENCODING = "ISO-8859-1";
|
||||||
|
|
||||||
int Encoder::calculateMaskPenalty(const ByteMatrix& matrix)
|
int Encoder::calculateMaskPenalty(const ByteMatrix& matrix)
|
||||||
{
|
{
|
||||||
@ -48,97 +51,98 @@ int Encoder::calculateMaskPenalty(const ByteMatrix& matrix)
|
|||||||
+ MaskUtil::applyMaskPenaltyRule4(matrix);
|
+ MaskUtil::applyMaskPenaltyRule4(matrix);
|
||||||
}
|
}
|
||||||
|
|
||||||
QRCode* Encoder::encode(const QString& content, const ErrorCorrectionLevel *ecLevel)
|
Ref<QRCode> Encoder::encode(const QString& content, Ref<ErrorCorrectionLevel> ecLevel)
|
||||||
{
|
{
|
||||||
return encode(content, ecLevel, NULL);
|
return encode(content, ecLevel, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
QRCode* Encoder::encode(const QString& content, const ErrorCorrectionLevel* ecLevel, const EncodeHint* hints)
|
Ref<QRCode> Encoder::encode(const QString& content, Ref<ErrorCorrectionLevel> ecLevel, const EncodeHint* hints)
|
||||||
{
|
{
|
||||||
// // Determine what character encoding has been specified by the caller, if any
|
// Determine what character encoding has been specified by the caller, if any
|
||||||
// QString encoding = hints == NULL ? "" : hints->get_character_set();
|
QString encoding = hints == NULL ? "" : QString(hints->getCharacterSet().c_str());
|
||||||
// if (encoding == "")
|
if (encoding == "")
|
||||||
// encoding = DEFAULT_BYTE_MODE_ENCODING;
|
encoding = DEFAULT_BYTE_MODE_ENCODING;
|
||||||
|
|
||||||
// // 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::getCharacterSetECIByName(encoding);
|
zxing::common::CharacterSetECI* eci =
|
||||||
// if (eci != NULL) {
|
zxing::common::CharacterSetECI::getCharacterSetECIByName(encoding.toStdString().c_str());
|
||||||
// appendECI(*eci, headerBits);
|
if (eci != NULL) {
|
||||||
// }
|
appendECI(*eci, headerBits);
|
||||||
// }
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// // (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();
|
||||||
// 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();
|
||||||
// Version version = chooseVersion(bitsNeeded, ecLevel);
|
Ref<Version> version = chooseVersion(bitsNeeded, *ecLevel);
|
||||||
|
|
||||||
// BitArray headerAndDataBits = new BitArray();
|
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.getSize() : 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);
|
||||||
|
|
||||||
// Version.ECBlocks ecBlocks = version.getECBlocksForLevel(ecLevel);
|
zxing::qrcode::ECBlocks ecBlocks = version->getECBlocksForLevel(*ecLevel);
|
||||||
// int numDataBytes = version.getTotalCodewords() - ecBlocks.getTotalECCodewords();
|
int numDataBytes = version->getTotalCodewords() - ecBlocks.getTotalECCodewords();
|
||||||
|
|
||||||
// // Terminate the bits properly.
|
// Terminate the bits properly.
|
||||||
// terminateBits(numDataBytes, headerAndDataBits);
|
terminateBits(numDataBytes, headerAndDataBits);
|
||||||
|
|
||||||
// // Interleave data bits with error correction code.
|
// Interleave data bits with error correction code.
|
||||||
// BitArray finalBits = interleaveWithECBytes(headerAndDataBits,
|
Ref<BitArray> finalBits(interleaveWithECBytes(headerAndDataBits,
|
||||||
// version.getTotalCodewords(),
|
version->getTotalCodewords(),
|
||||||
// numDataBytes,
|
numDataBytes,
|
||||||
// ecBlocks.getNumBlocks());
|
1));//ecBlocks->getNumBlocks());
|
||||||
|
|
||||||
// QRCode qrCode = new QRCode();
|
Ref<QRCode> qrCode(new QRCode);
|
||||||
|
|
||||||
// qrCode.setECLevel(ecLevel);
|
qrCode->setECLevel(ecLevel);
|
||||||
// qrCode.setMode(mode);
|
qrCode->setMode(Ref<Mode>(mode));
|
||||||
// qrCode.setVersion(version);
|
qrCode->setVersion(version);
|
||||||
|
|
||||||
// // Choose the mask pattern and set to "qrCode".
|
// Choose the mask pattern and set to "qrCode".
|
||||||
// int dimension = version.getDimensionForVersion();
|
int dimension = version->getDimensionForVersion();
|
||||||
// ByteMatrix matrix = new ByteMatrix(dimension, dimension);
|
Ref<ByteMatrix> matrix(new ByteMatrix(dimension, dimension));
|
||||||
// int maskPattern = chooseMaskPattern(finalBits, ecLevel, version, matrix);
|
int maskPattern = chooseMaskPattern(finalBits, *ecLevel, version, matrix);
|
||||||
// qrCode.setMaskPattern(maskPattern);
|
qrCode->setMaskPattern(maskPattern);
|
||||||
|
|
||||||
// // Build the matrix and set it to "qrCode".
|
// Build the matrix and set it to "qrCode".
|
||||||
// MatrixUtil.buildMatrix(finalBits, ecLevel, version, maskPattern, matrix);
|
MatrixUtil::buildMatrix(*finalBits, *ecLevel, *version, maskPattern, *matrix);
|
||||||
// qrCode.setMatrix(matrix);
|
qrCode->setMatrix(matrix);
|
||||||
|
|
||||||
// return qrCode;
|
return qrCode;
|
||||||
|
|
||||||
return NULL;
|
//return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -209,35 +213,36 @@ Mode* Encoder::chooseMode(const QString& content, const QString& encoding)
|
|||||||
// return true;
|
// return true;
|
||||||
//}
|
//}
|
||||||
|
|
||||||
// private static int chooseMaskPattern(BitArray bits,
|
int Encoder::chooseMaskPattern(Ref<BitArray> bits,
|
||||||
// ErrorCorrectionLevel ecLevel,
|
ErrorCorrectionLevel ecLevel,
|
||||||
// Version version,
|
Ref<Version> version,
|
||||||
// ByteMatrix matrix) throws WriterException {
|
Ref<ByteMatrix> matrix)
|
||||||
|
{
|
||||||
|
|
||||||
// int minPenalty = Integer.MAX_VALUE; // Lower penalty is better.
|
int minPenalty = std::numeric_limits<int>::max(); // Lower penalty is better.
|
||||||
// int bestMaskPattern = -1;
|
int bestMaskPattern = -1;
|
||||||
// // We try all mask patterns to choose the best one.
|
// We try all mask patterns to choose the best one.
|
||||||
// for (int maskPattern = 0; maskPattern < QRCode.NUM_MASK_PATTERNS; maskPattern++) {
|
for (int maskPattern = 0; maskPattern < QRCode::NUM_MASK_PATTERNS; maskPattern++) {
|
||||||
// MatrixUtil.buildMatrix(bits, ecLevel, version, maskPattern, matrix);
|
MatrixUtil::buildMatrix(*bits, ecLevel, *version, maskPattern, *matrix);
|
||||||
// int penalty = calculateMaskPenalty(matrix);
|
int penalty = calculateMaskPenalty(*matrix);
|
||||||
// if (penalty < minPenalty) {
|
if (penalty < minPenalty) {
|
||||||
// minPenalty = penalty;
|
minPenalty = penalty;
|
||||||
// bestMaskPattern = maskPattern;
|
bestMaskPattern = maskPattern;
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
// return bestMaskPattern;
|
return bestMaskPattern;
|
||||||
// }
|
}
|
||||||
|
|
||||||
Version Encoder::chooseVersion(int numInputBits, ErrorCorrectionLevel &ecLevel)
|
Ref<Version> Encoder::chooseVersion(int numInputBits, const ErrorCorrectionLevel &ecLevel)
|
||||||
{
|
{
|
||||||
// In the following comments, we use numbers of Version 7-H.
|
// In the following comments, we use numbers of Version 7-H.
|
||||||
for (int versionNum = 1; versionNum <= 40; versionNum++) {
|
for (int versionNum = 1; versionNum <= 40; versionNum++) {
|
||||||
Version& version = *Version::getVersionForNumber(versionNum);
|
Ref<Version> version = Version::getVersionForNumber(versionNum);
|
||||||
// numBytes = 196
|
// numBytes = 196
|
||||||
int numBytes = version.getTotalCodewords();
|
int numBytes = version->getTotalCodewords();
|
||||||
// getNumECBytes = 130
|
// getNumECBytes = 130
|
||||||
ECBlocks& ecBlocks = version.getECBlocksForLevel(ecLevel);
|
ECBlocks& ecBlocks = version->getECBlocksForLevel(ecLevel);
|
||||||
int numEcBytes = ecBlocks.getECCodewords();
|
int numEcBytes = ecBlocks.getTotalECCodewords();
|
||||||
// getNumDataBytes = 196 - 130 = 66
|
// getNumDataBytes = 196 - 130 = 66
|
||||||
int numDataBytes = numBytes - numEcBytes;
|
int numDataBytes = numBytes - numEcBytes;
|
||||||
int totalInputBytes = (numInputBits + 7) / 8;
|
int totalInputBytes = (numInputBits + 7) / 8;
|
||||||
@ -357,9 +362,8 @@ BitArray* Encoder::interleaveWithECBytes(const BitArray& bits,
|
|||||||
{
|
{
|
||||||
|
|
||||||
// "bits" must have "getNumDataBytes" bytes of data.
|
// "bits" must have "getNumDataBytes" bytes of data.
|
||||||
if (bits.getSize() != numDataBytes) {
|
if (bits.getSize() != numDataBytes)
|
||||||
throw new WriterException("Number of bits and data bytes does not match");
|
throw new WriterException("Number of bits and data bytes does not match");
|
||||||
}
|
|
||||||
|
|
||||||
// Step 1. Divide data bytes into blocks and generate error correction bytes for them. We'll
|
// Step 1. Divide data bytes into blocks and generate error correction bytes for them. We'll
|
||||||
// store the divided data bytes blocks and error correction bytes blocks into "blocks".
|
// store the divided data bytes blocks and error correction bytes blocks into "blocks".
|
||||||
@ -441,142 +445,152 @@ ArrayRef<char> Encoder::generateECBytes(const std::vector<char>& dataBytes, int
|
|||||||
return ecBytes;
|
return ecBytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
// /**
|
/**
|
||||||
// * Append mode info. On success, store the result in "bits".
|
* Append mode info. On success, store the result in "bits".
|
||||||
// */
|
*/
|
||||||
// static void appendModeInfo(Mode mode, BitArray bits) {
|
void Encoder::appendModeInfo(const Mode& mode, BitArray& bits)
|
||||||
// bits.appendBits(mode.getBits(), 4);
|
{
|
||||||
// }
|
bits.appendBits(mode.getBits(), 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// /**
|
|
||||||
// * Append length info. On success, store the result in "bits".
|
|
||||||
// */
|
|
||||||
// static void appendLengthInfo(int numLetters, Version version, Mode mode, BitArray bits) throws WriterException {
|
|
||||||
// int numBits = mode.getCharacterCountBits(version);
|
|
||||||
// if (numLetters >= (1 << numBits)) {
|
|
||||||
// throw new WriterException(numLetters + " is bigger than " + ((1 << numBits) - 1));
|
|
||||||
// }
|
|
||||||
// bits.appendBits(numLetters, numBits);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// /**
|
/**
|
||||||
// * Append "bytes" in "mode" mode (encoding) into "bits". On success, store the result in "bits".
|
* Append length info. On success, store the result in "bits".
|
||||||
// */
|
*/
|
||||||
// static void appendBytes(String content,
|
void Encoder::appendLengthInfo(int numLetters, const Version& version, const Mode& mode, BitArray& bits)
|
||||||
// Mode mode,
|
{
|
||||||
// BitArray bits,
|
int numBits = mode.getCharacterCountBits(&version);
|
||||||
// String encoding) throws WriterException {
|
if (numLetters >= (1 << numBits)) {
|
||||||
// switch (mode) {
|
QString message = QString::number(numLetters);
|
||||||
// case NUMERIC:
|
message += " is bigger than ";
|
||||||
// appendNumericBytes(content, bits);
|
message += QString::number((1 << numBits) - 1);
|
||||||
// break;
|
|
||||||
// case ALPHANUMERIC:
|
|
||||||
// appendAlphanumericBytes(content, bits);
|
|
||||||
// break;
|
|
||||||
// case BYTE:
|
|
||||||
// append8BitBytes(content, bits, encoding);
|
|
||||||
// break;
|
|
||||||
// case KANJI:
|
|
||||||
// appendKanjiBytes(content, bits);
|
|
||||||
// break;
|
|
||||||
// default:
|
|
||||||
// throw new WriterException("Invalid mode: " + mode);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// static void appendNumericBytes(CharSequence content, BitArray bits) {
|
throw new WriterException(message.toStdString().c_str());
|
||||||
// int length = content.length();
|
}
|
||||||
// int i = 0;
|
bits.appendBits(numLetters, numBits);
|
||||||
// while (i < length) {
|
}
|
||||||
// int num1 = content.charAt(i) - '0';
|
|
||||||
// if (i + 2 < length) {
|
|
||||||
// // Encode three numeric letters in ten bits.
|
|
||||||
// int num2 = content.charAt(i + 1) - '0';
|
|
||||||
// int num3 = content.charAt(i + 2) - '0';
|
|
||||||
// bits.appendBits(num1 * 100 + num2 * 10 + num3, 10);
|
|
||||||
// i += 3;
|
|
||||||
// } else if (i + 1 < length) {
|
|
||||||
// // Encode two numeric letters in seven bits.
|
|
||||||
// int num2 = content.charAt(i + 1) - '0';
|
|
||||||
// bits.appendBits(num1 * 10 + num2, 7);
|
|
||||||
// i += 2;
|
|
||||||
// } else {
|
|
||||||
// // Encode one numeric letter in four bits.
|
|
||||||
// bits.appendBits(num1, 4);
|
|
||||||
// i++;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// static void appendAlphanumericBytes(CharSequence content, BitArray bits) throws WriterException {
|
/**
|
||||||
// int length = content.length();
|
* Append "bytes" in "mode" mode (encoding) into "bits". On success, store the result in "bits".
|
||||||
// int i = 0;
|
*/
|
||||||
// while (i < length) {
|
void Encoder::appendBytes(const QString& content,
|
||||||
// int code1 = getAlphanumericCode(content.charAt(i));
|
Mode& mode,
|
||||||
// if (code1 == -1) {
|
BitArray& bits,
|
||||||
// throw new WriterException();
|
const QString& encoding)
|
||||||
// }
|
{
|
||||||
// if (i + 1 < length) {
|
if (mode == Mode::NUMERIC)
|
||||||
// int code2 = getAlphanumericCode(content.charAt(i + 1));
|
appendNumericBytes(content, bits);
|
||||||
// if (code2 == -1) {
|
else if (mode == Mode::ALPHANUMERIC)
|
||||||
// throw new WriterException();
|
appendAlphanumericBytes(content, bits);
|
||||||
// }
|
else if (mode == Mode::BYTE)
|
||||||
// // Encode two alphanumeric letters in 11 bits.
|
append8BitBytes(content, bits, encoding);
|
||||||
// bits.appendBits(code1 * 45 + code2, 11);
|
else if (mode == Mode::KANJI)
|
||||||
// i += 2;
|
appendKanjiBytes(content, bits);
|
||||||
// } else {
|
else {
|
||||||
// // Encode one alphanumeric letter in six bits.
|
QString message("Invalid mode: ");
|
||||||
// bits.appendBits(code1, 6);
|
message += QString::fromStdString(mode.getName());
|
||||||
// i++;
|
throw new WriterException(message.toStdString().c_str());
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
// }
|
|
||||||
|
|
||||||
// static void append8BitBytes(String content, BitArray bits, String encoding)
|
void Encoder::appendNumericBytes( const QString& content, BitArray& bits)
|
||||||
// throws WriterException {
|
{
|
||||||
// byte[] bytes;
|
int length = content.size();
|
||||||
// try {
|
int i = 0;
|
||||||
// bytes = content.getBytes(encoding);
|
while (i < length) {
|
||||||
// } catch (UnsupportedEncodingException uee) {
|
int num1 = content.at(i).toLatin1() - '0';
|
||||||
// throw new WriterException(uee);
|
if (i + 2 < length) {
|
||||||
// }
|
// Encode three numeric letters in ten bits.
|
||||||
// for (byte b : bytes) {
|
int num2 = content.at(i + 1).toLatin1() - '0';
|
||||||
// bits.appendBits(b, 8);
|
int num3 = content.at(i + 2).toLatin1() - '0';
|
||||||
// }
|
bits.appendBits(num1 * 100 + num2 * 10 + num3, 10);
|
||||||
// }
|
i += 3;
|
||||||
|
} else if (i + 1 < length) {
|
||||||
|
// Encode two numeric letters in seven bits.
|
||||||
|
int num2 = content.at(i + 1).toLatin1() - '0';
|
||||||
|
bits.appendBits(num1 * 10 + num2, 7);
|
||||||
|
i += 2;
|
||||||
|
} else {
|
||||||
|
// Encode one numeric letter in four bits.
|
||||||
|
bits.appendBits(num1, 4);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// static void appendKanjiBytes(String content, BitArray bits) throws WriterException {
|
void Encoder::appendAlphanumericBytes(const QString& content, BitArray& bits)
|
||||||
// byte[] bytes;
|
{
|
||||||
// try {
|
int length = content.length();
|
||||||
// bytes = content.getBytes("Shift_JIS");
|
int i = 0;
|
||||||
// } catch (UnsupportedEncodingException uee) {
|
while (i < length) {
|
||||||
// throw new WriterException(uee);
|
int code1 = getAlphanumericCode(content.at(i).toLatin1());
|
||||||
// }
|
if (code1 == -1) {
|
||||||
// int length = bytes.length;
|
throw new WriterException();
|
||||||
// for (int i = 0; i < length; i += 2) {
|
}
|
||||||
// int byte1 = bytes[i] & 0xFF;
|
if (i + 1 < length) {
|
||||||
// int byte2 = bytes[i + 1] & 0xFF;
|
int code2 = getAlphanumericCode(content.at(i + 1).toLatin1());
|
||||||
// int code = (byte1 << 8) | byte2;
|
if (code2 == -1) {
|
||||||
// int subtracted = -1;
|
throw new WriterException();
|
||||||
// if (code >= 0x8140 && code <= 0x9ffc) {
|
}
|
||||||
// subtracted = code - 0x8140;
|
// Encode two alphanumeric letters in 11 bits.
|
||||||
// } else if (code >= 0xe040 && code <= 0xebbf) {
|
bits.appendBits(code1 * 45 + code2, 11);
|
||||||
// subtracted = code - 0xc140;
|
i += 2;
|
||||||
// }
|
} else {
|
||||||
// if (subtracted == -1) {
|
// Encode one alphanumeric letter in six bits.
|
||||||
// throw new WriterException("Invalid byte sequence");
|
bits.appendBits(code1, 6);
|
||||||
// }
|
i++;
|
||||||
// int encoded = ((subtracted >> 8) * 0xc0) + (subtracted & 0xff);
|
}
|
||||||
// bits.appendBits(encoded, 13);
|
}
|
||||||
// }
|
}
|
||||||
// }
|
|
||||||
|
|
||||||
// private static void appendECI(CharacterSetECI eci, BitArray bits) {
|
void Encoder::append8BitBytes(const QString& content, BitArray& bits, const QString& /*encoding*/)
|
||||||
// bits.appendBits(Mode.ECI.getBits(), 4);
|
{
|
||||||
// // This is correct for values up to 127, which is all we need now.
|
// For now we will suppose that all the encoding has been handled by QString class.
|
||||||
// bits.appendBits(eci.getValue(), 8);
|
// byte[] bytes;
|
||||||
// }
|
// try {
|
||||||
|
// bytes = content.getBytes(encoding);
|
||||||
|
// } catch (UnsupportedEncodingException uee) {
|
||||||
|
// throw new WriterException(uee);
|
||||||
|
// }
|
||||||
|
|
||||||
|
for (int i=0; i<content.size(); ++i) {
|
||||||
|
bits.appendBits(content.at(i).toLatin1(), 8);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Encoder::appendKanjiBytes(const QString& content, BitArray& bits)
|
||||||
|
{
|
||||||
|
// For now we will suppose that all the encoding has been handled by QString class.
|
||||||
|
// try {
|
||||||
|
// bytes = content.getBytes("Shift_JIS");
|
||||||
|
// } catch (UnsupportedEncodingException uee) {
|
||||||
|
// throw new WriterException(uee);
|
||||||
|
// }
|
||||||
|
int length = content.size();
|
||||||
|
for (int i = 0; i < length; i += 2) {
|
||||||
|
int byte1 = content.at(i).toLatin1() & 0xFF;
|
||||||
|
int byte2 = content.at(i + 1).toLatin1() & 0xFF;
|
||||||
|
int code = (byte1 << 8) | byte2;
|
||||||
|
int subtracted = -1;
|
||||||
|
if (code >= 0x8140 && code <= 0x9ffc) {
|
||||||
|
subtracted = code - 0x8140;
|
||||||
|
} else if (code >= 0xe040 && code <= 0xebbf) {
|
||||||
|
subtracted = code - 0xc140;
|
||||||
|
}
|
||||||
|
if (subtracted == -1) {
|
||||||
|
throw new WriterException("Invalid byte sequence");
|
||||||
|
}
|
||||||
|
int encoded = ((subtracted >> 8) * 0xc0) + (subtracted & 0xff);
|
||||||
|
bits.appendBits(encoded, 13);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Encoder::appendECI(const zxing::common::CharacterSetECI& eci, BitArray& bits) {
|
||||||
|
bits.appendBits(Mode::ECI.getBits(), 4);
|
||||||
|
// This is correct for values up to 127, which is all we need now.
|
||||||
|
bits.appendBits(eci.getValue(), 8);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -38,9 +38,9 @@ private:
|
|||||||
* with which clients can specify the encoding mode. For now, we don't need the functionality.
|
* with which clients can specify the encoding mode. For now, we don't need the functionality.
|
||||||
*/
|
*/
|
||||||
public:
|
public:
|
||||||
static QRCode* encode(const QString& content, const ErrorCorrectionLevel* ecLevel);
|
static Ref<QRCode> encode(const QString& content, Ref<ErrorCorrectionLevel> ecLevel);
|
||||||
|
|
||||||
static QRCode* encode(const QString& content, const ErrorCorrectionLevel* ecLevel, const EncodeHint* hints);
|
static Ref<QRCode> encode(const QString& content, Ref<ErrorCorrectionLevel> ecLevel, const EncodeHint* hints);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the code point of the table used in alphanumeric mode or
|
* @return the code point of the table used in alphanumeric mode or
|
||||||
@ -59,12 +59,12 @@ private:
|
|||||||
|
|
||||||
//static bool isOnlyDoubleByteKanji(const QString& content);
|
//static bool isOnlyDoubleByteKanji(const QString& content);
|
||||||
|
|
||||||
static int chooseMaskPattern(BitArray bits,
|
static int chooseMaskPattern(Ref<BitArray> bits,
|
||||||
ErrorCorrectionLevel ecLevel,
|
ErrorCorrectionLevel ecLevel,
|
||||||
Version version,
|
Ref<Version> version,
|
||||||
ByteMatrix matrix);
|
Ref<ByteMatrix> matrix);
|
||||||
|
|
||||||
static Version chooseVersion(int numInputBits, ErrorCorrectionLevel &ecLevel) ;
|
static Ref<Version> chooseVersion(int numInputBits, const ErrorCorrectionLevel &ecLevel) ;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Terminate bits as described in 8.4.8 and 8.4.9 of JISX0510:2004 (p.24).
|
* Terminate bits as described in 8.4.8 and 8.4.9 of JISX0510:2004 (p.24).
|
||||||
@ -98,7 +98,7 @@ protected:
|
|||||||
/**
|
/**
|
||||||
* Append mode info. On success, store the result in "bits".
|
* Append mode info. On success, store the result in "bits".
|
||||||
*/
|
*/
|
||||||
static void appendModeInfo(const Mode& mode, BitArray& bits);
|
static void appendModeInfo(const Mode& mode, BitArray &bits);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -110,13 +110,13 @@ protected:
|
|||||||
* Append "bytes" in "mode" mode (encoding) into "bits". On success, store the result in "bits".
|
* Append "bytes" in "mode" mode (encoding) into "bits". On success, store the result in "bits".
|
||||||
*/
|
*/
|
||||||
static void appendBytes(const QString& content,
|
static void appendBytes(const QString& content,
|
||||||
const Mode& mode,
|
Mode& mode,
|
||||||
BitArray& bits,
|
BitArray& bits,
|
||||||
const QString& encoding);
|
const QString& encoding);
|
||||||
|
|
||||||
static void appendNumericBytes( const std::vector<char>& content, BitArray& bits);
|
static void appendNumericBytes(const QString& content, BitArray& bits);
|
||||||
|
|
||||||
static void appendAlphanumericBytes(const std::vector<char>& content, BitArray& bits);
|
static void appendAlphanumericBytes(const QString& content, BitArray& bits);
|
||||||
|
|
||||||
static void append8BitBytes(const QString& content, BitArray& bits, const QString& encoding);
|
static void append8BitBytes(const QString& content, BitArray& bits, const QString& encoding);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user