Skip to content

Commit

Permalink
Fix bitcount info length calculation, Symbols with versions larger th…
Browse files Browse the repository at this point in the history
…an 9 should work propperly now
  • Loading branch information
Joel Sutter committed Jun 17, 2011
1 parent 33dd434 commit 923b445
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 30 deletions.
19 changes: 3 additions & 16 deletions include/dataencoder.h
Expand Up @@ -10,24 +10,11 @@ static const byte Terminator = 0; // 0000
static const byte Padding[] = {236, 17}; // 11101100 and 00010001


/*
* This needs to be extended
* now only Version 1-9 are coded
* Version Numeric Alpha Byte
* 1 - 9 10 9 8
* 10 - 26 12 11 16
* 27 - 40 13 13 16
*/
typedef enum {
CountByte = 8,
CountAlpha, // 9
CountNumeric // 10
} CharacterCountBitsCount;

struct SymbolInfo;

bool encodeData(bitstream* bs, const SymbolInfo* si);
int getBitCount(int numChars, EncodeModeIndicator mode);
int getByteCount(int numChars, EncodeModeIndicator mode);
int getBitCount(int numChars, EncodeModeIndicator mode, int version);
int getByteCount(int numChars, EncodeModeIndicator mode, int version);
int getCharacterCountBitCount(EncodeModeIndicator mode, int version);

#endif //DATAENCODER_H
60 changes: 50 additions & 10 deletions src/qrgen/dataencoder.c
Expand Up @@ -18,26 +18,25 @@ bool encodeData(bitstream* bs, const SymbolInfo* si)


bool (*encode)(bitstream* bs, const byte* data, int dataSize) = NULL; /* Mode specific encode routine */
CharacterCountBitsCount ccbc = 0; /* Mode specific size of Character Count Information */
int ccbc = 0; /* Mode specific size of Character Count Information */

switch(si->encodeMode) {
case ModeByte:
ccbc = CountByte;
encode = &encodeByte;
break;
case ModeAlpha:
ccbc = CountAlpha;
encode = &encodeAlpha;
break;
case ModeNumeric:
ccbc = CountNumeric;
encode = &encodeNumeric;
break;
default:
error("Mode not supported: %d", si->encodeMode);
return false;
}

ccbc = getCharacterCountBitCount(si->encodeMode, si->version);

bs_add_b(bs, si->encodeMode, 4); /* add Mode information*/
bs_add_i(bs, si->dataCount, ccbc); /* add Character count information */
bool ret = (*encode)(bs, si->inputData, si->dataCount); /* add data, mode speicific */
Expand All @@ -63,22 +62,22 @@ bool encodeData(bitstream* bs, const SymbolInfo* si)
}


int getBitCount(int numChars, EncodeModeIndicator mode)
int getBitCount(int numChars, EncodeModeIndicator mode, int version)
{
switch(mode) {
case ModeNumeric:
return 4 + CountNumeric + 10 * (numChars / 3) + ((numChars % 3 == 0) ? 0 : ((numChars % 3 == 1) ? 4 : 7));
return 4 + getCharacterCountBitCount(mode, version) + 10 * (numChars / 3) + ((numChars % 3 == 0) ? 0 : ((numChars % 3 == 1) ? 4 : 7));
case ModeAlpha:
return 4 + CountAlpha + 11 * (numChars / 2) + 6 *(numChars % 2);
return 4 + getCharacterCountBitCount(mode, version) + 11 * (numChars / 2) + 6 *(numChars % 2);
case ModeByte:
return 4 + CountByte + 8 * numChars;
return 4 + getCharacterCountBitCount(mode, version) + 8 * numChars;
}
return 0;
}

int getByteCount(int numChars, EncodeModeIndicator mode)
int getByteCount(int numChars, EncodeModeIndicator mode, int version)
{
int tmp = getBitCount(numChars, mode);
int tmp = getBitCount(numChars, mode, version);
return tmp / 8 + ((tmp % 8) ? 1 : 0);
}

Expand Down Expand Up @@ -180,5 +179,46 @@ byte alphaValue(byte alpha)
error("Character not usable in alpha mode: %c", alpha);

return -1;
}

int getCharacterCountBitCount(EncodeModeIndicator mode, int version)
{
/*
* Version Numeric Alpha Byte
* 1 - 9 10 9 8
* 10 - 26 12 11 16
* 27 - 40 13 13 16
*/
switch(mode)
{
case ModeNumeric:
if (version >= 1 && version <= 9)
return 10;
else if (version >= 10 && version <= 26)
return 12;
else if (version >= 27 && version <= 40)
return 13;
break;
case ModeAlpha:
if (version >= 1 && version <= 9)
return 9;
else if (version >= 10 && version <= 26)
return 11;
else if (version >= 27 && version <= 40)
return 13;
break;
case ModeByte:
if (version >= 1 && version <= 9)
return 8;
else if (version >= 10 && version <= 26)
return 16;
else if (version >= 27 && version <= 40)
return 16;
break;
default:
error("Mode %d invalid", mode);
return -1;
}
error("Version %d invalid", version);
return -1;
}
10 changes: 6 additions & 4 deletions src/qrgen/symbolinfo.c
Expand Up @@ -165,7 +165,7 @@ bool si_encode(SymbolInfo* si)
si->ecCodeWords = get_ec_codewords(si->version, si->ecLevel);
si->dataCodeWords = get_data_codewords(si->version, si->ecLevel);
si->blockInfo = get_block_info(si->version, si->ecLevel);
si->encodedDataCount = getByteCount(si->dataCount, si->encodeMode);
si->encodedDataCount = getByteCount(si->dataCount, si->encodeMode, si->version);

/* 2. encode data */
bitstream* bs = bs_init();
Expand Down Expand Up @@ -208,11 +208,13 @@ bool si_encode(SymbolInfo* si)

int get_min_version(int dataCount, int encMode, int ecLevel)
{
dataCount = getByteCount(dataCount, encMode);
int byteCount;
int i;
if (dataCount < 0 || ecLevel < 0 || ecLevel > 3) return 0;
for (i = 0; i < 40; i++) {
if (get_data_codewords(i+1, ecLevel) >= dataCount) return i+1;
for (i = 1; i <= 40; i++) {
//at version 10 and 27 The characterCountDataLength changes, so recalculate the whole length
if (i == 1 || i == 10 || i == 27) byteCount = getByteCount(dataCount, encMode, i);
if (get_data_codewords(i, ecLevel) >= byteCount) return i;
}
return 0;
}
Expand Down

0 comments on commit 923b445

Please sign in to comment.