2 * qrencode - QR Code encoder
4 * Copyright (C) 2006, 2007, 2008, 2009 Kentaro Fukuchi <fukuchi@megaui.net>
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
29 #include "bitstream.h"
35 /******************************************************************************
37 *****************************************************************************/
48 unsigned char *datacode;
49 unsigned char *ecccode;
58 static void RSblock_initBlock(RSblock *block, int dl, unsigned char *data, int el, unsigned char *ecc, RS *rs)
60 block->dataLength = dl;
62 block->eccLength = el;
65 encode_rs_char(rs, data, ecc);
68 static int RSblock_init(RSblock *blocks, int spec[5], unsigned char *data, unsigned char *ecc)
72 unsigned char *dp, *ep;
76 dl = QRspec_rsDataCodes1(spec);
77 el = QRspec_rsEccCodes1(spec);
78 rs = init_rs(8, 0x11d, 0, 1, el, 255 - dl - el);
79 if(rs == NULL) return -1;
84 for(i=0; i<QRspec_rsBlockNum1(spec); i++) {
85 RSblock_initBlock(block, dl, dp, el, ep, rs);
91 if(QRspec_rsBlockNum2(spec) == 0) return 0;
93 dl = QRspec_rsDataCodes2(spec);
94 el = QRspec_rsEccCodes2(spec);
95 rs = init_rs(8, 0x11d, 0, 1, el, 255 - dl - el);
96 if(rs == NULL) return -1;
97 for(i=0; i<QRspec_rsBlockNum2(spec); i++) {
98 RSblock_initBlock(block, dl, dp, el, ep, rs);
107 __STATIC void QRraw_free(QRRawCode *raw);
108 __STATIC QRRawCode *QRraw_new(QRinput *input)
113 raw = (QRRawCode *)malloc(sizeof(QRRawCode));
114 if(raw == NULL) return NULL;
116 raw->datacode = QRinput_getByteStream(input);
117 if(raw->datacode == NULL) {
122 QRspec_getEccSpec(input->version, input->level, spec);
124 raw->version = input->version;
125 raw->b1 = QRspec_rsBlockNum1(spec);
126 raw->dataLength = QRspec_rsDataLength(spec);
127 raw->eccLength = QRspec_rsEccLength(spec);
128 raw->ecccode = (unsigned char *)malloc(raw->eccLength);
129 if(raw->ecccode == NULL) {
135 raw->blocks = QRspec_rsBlockNum(spec);
136 raw->rsblock = (RSblock *)calloc(sizeof(RSblock), raw->blocks);
137 if(raw->rsblock == NULL) {
141 ret = RSblock_init(raw->rsblock, spec, raw->datacode, raw->ecccode);
153 * Return a code (byte).
154 * This function can be called iteratively.
155 * @param raw raw code.
158 __STATIC unsigned char QRraw_getCode(QRRawCode *raw)
163 if(raw->count < raw->dataLength) {
164 row = raw->count % raw->blocks;
165 col = raw->count / raw->blocks;
166 if(col >= raw->rsblock[row].dataLength) {
169 ret = raw->rsblock[row].data[col];
170 } else if(raw->count < raw->dataLength + raw->eccLength) {
171 row = (raw->count - raw->dataLength) % raw->blocks;
172 col = (raw->count - raw->dataLength) / raw->blocks;
173 ret = raw->rsblock[row].ecc[col];
181 __STATIC void QRraw_free(QRRawCode *raw)
186 if(raw->rsblock != NULL) {
193 /******************************************************************************
195 *****************************************************************************/
199 unsigned char *frame;
205 static FrameFiller *FrameFiller_new(int width, unsigned char *frame)
209 filler = (FrameFiller *)malloc(sizeof(FrameFiller));
210 if(filler == NULL) return NULL;
211 filler->width = width;
212 filler->frame = frame;
213 filler->x = width - 1;
214 filler->y = width - 1;
221 static unsigned char *FrameFiller_next(FrameFiller *filler)
226 if(filler->bit == -1) {
228 return filler->frame + filler->y * filler->width + filler->x;
236 if(filler->bit == 0) {
245 if(filler->dir < 0) {
266 if(x < 0 || y < 0) return NULL;
271 if(p[y * w + x] & 0x80) {
272 // This tail recursion could be optimized.
273 return FrameFiller_next(filler);
275 return &p[y * w + x];
279 unsigned char *FrameFiller_fillerTest(int version)
282 unsigned char *frame, *p;
285 unsigned char cl = 1;
286 unsigned char ch = 0;
288 width = QRspec_getWidth(version);
289 frame = QRspec_newFrame(version);
290 filler = FrameFiller_new(width, frame);
291 length = QRspec_getDataLength(version, QR_ECLEVEL_L)
292 + QRspec_getECCLength(version, QR_ECLEVEL_L);
294 for(i=0; i<length; i++) {
296 p = FrameFiller_next(filler);
305 length = QRspec_getRemainder(version);
306 for(i=0; i<length; i++) {
307 p = FrameFiller_next(filler);
310 p = FrameFiller_next(filler);
321 /******************************************************************************
323 *****************************************************************************/
325 static QRcode *QRcode_new(int version, int width, unsigned char *data)
329 qrcode = (QRcode *)malloc(sizeof(QRcode));
330 if(qrcode == NULL) return NULL;
332 qrcode->version = version;
333 qrcode->width = width;
339 void QRcode_free(QRcode *qrcode)
347 __STATIC QRcode *QRcode_encodeMask(QRinput *input, int mask)
351 unsigned char *frame, *masked, *p, code, bit;
356 if(input->version < 0 || input->version > QRSPEC_VERSION_MAX) {
360 if(input->level > QR_ECLEVEL_H) {
365 raw = QRraw_new(input);
366 if(raw == NULL) return NULL;
368 version = raw->version;
369 width = QRspec_getWidth(version);
370 frame = QRspec_newFrame(version);
375 filler = FrameFiller_new(width, frame);
382 /* inteleaved data and ecc codes */
383 for(i=0; i<raw->dataLength + raw->eccLength; i++) {
384 code = QRraw_getCode(raw);
387 p = FrameFiller_next(filler);
388 *p = 0x02 | ((bit & code) != 0);
394 j = QRspec_getRemainder(version);
396 p = FrameFiller_next(filler);
402 masked = Mask_mask(width, frame, input->level);
404 masked = Mask_makeMask(width, frame, mask, input->level);
410 qrcode = QRcode_new(version, width, masked);
417 QRcode *QRcode_encodeInput(QRinput *input)
419 return QRcode_encodeMask(input, -1);
422 QRcode *QRcode_encodeString8bit(const char *string, int version, QRecLevel level)
433 input = QRinput_new2(version, level);
434 if(input == NULL) return NULL;
436 ret = QRinput_append(input, QR_MODE_8, strlen(string), (unsigned char *)string);
441 code = QRcode_encodeInput(input);
447 QRcode *QRcode_encodeString(const char *string, int version, QRecLevel level, QRencodeMode hint, int casesensitive)
453 if(hint != QR_MODE_8 && hint != QR_MODE_KANJI) {
458 input = QRinput_new2(version, level);
459 if(input == NULL) return NULL;
461 ret = Split_splitStringToQRinput(string, input, hint, casesensitive);
467 code = QRcode_encodeInput(input);
473 /******************************************************************************
474 * Structured QR-code encoding
475 *****************************************************************************/
477 static QRcode_List *QRcode_List_newEntry(void)
481 entry = (QRcode_List *)malloc(sizeof(QRcode_List));
482 if(entry == NULL) return NULL;
490 static void QRcode_List_freeEntry(QRcode_List *entry)
493 QRcode_free(entry->code);
498 void QRcode_List_free(QRcode_List *qrlist)
500 QRcode_List *list = qrlist, *next;
502 while(list != NULL) {
504 QRcode_List_freeEntry(list);
509 int QRcode_List_size(QRcode_List *qrlist)
511 QRcode_List *list = qrlist;
514 while(list != NULL) {
523 static unsigned char QRcode_parity(const char *str, int size)
525 unsigned char parity = 0;
528 for(i=0; i<size; i++) {
536 QRcode_List *QRcode_encodeInputStructured(QRinput_Struct *s)
538 QRcode_List *head = NULL;
539 QRcode_List *tail = NULL;
541 QRinput_InputList *list = s->head;
543 while(list != NULL) {
545 entry = QRcode_List_newEntry();
546 if(entry == NULL) goto ABORT;
550 entry = QRcode_List_newEntry();
551 if(entry == NULL) goto ABORT;
555 tail->code = QRcode_encodeInput(list->input);
556 if(tail->code == NULL) {
564 QRcode_List_free(head);
568 static QRcode_List *QRcode_encodeInputToStructured(QRinput *input)
573 s = QRinput_splitQRinputToStruct(input);
574 if(s == NULL) return NULL;
576 codes = QRcode_encodeInputStructured(s);
577 QRinput_Struct_free(s);
582 QRcode_List *QRcode_encodeString8bitStructured(const char *string, int version, QRecLevel level)
593 input = QRinput_new2(version, level);
594 if(input == NULL) return NULL;
596 ret = QRinput_append(input, QR_MODE_8, strlen(string), (unsigned char *)string);
601 codes = QRcode_encodeInputToStructured(input);
607 QRcode_List *QRcode_encodeStringStructured(const char *string, int version, QRecLevel level, QRencodeMode hint, int casesensitive)
617 if(hint != QR_MODE_8 && hint != QR_MODE_KANJI) {
622 input = QRinput_new2(version, level);
623 if(input == NULL) return NULL;
625 ret = Split_splitStringToQRinput(string, input, hint, casesensitive);
630 codes = QRcode_encodeInputToStructured(input);