qrinput.c ( File view )

  • By green75 2014-11-06
  • View(s):334
  • Download(s):8
  • Point(s): 3
			/*
 * qrencode - QR Code encoder
 *
 * Input data chunk class
 * Copyright (C) 2006-2011 Kentaro Fukuchi <kentaro@fukuchi.org>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
 */

#if HAVE_CONFIG_H
# include "config.h"
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>

#include "qrencode.h"
#include "qrspec.h"
#include "mqrspec.h"
#include "bitstream.h"
#include "qrinput.h"

/******************************************************************************
 * Utilities
 *****************************************************************************/
int QRinput_isSplittableMode(QRencodeMode mode)
{

	return (mode >= QR_MODE_NUM && mode <= QR_MODE_KANJI);

}

/******************************************************************************
 * Entry of input data
 *****************************************************************************/

static QRinput_List *QRinput_List_newEntry(QRencodeMode mode, int size, const unsigned char *data)
{

	QRinput_List *entry;

	if(QRinput_check(mode, size, data)) {

		errno = EINVAL;
		return NULL;
	
}

	entry = (QRinput_List *)malloc(sizeof(QRinput_List));
	if(entry == NULL) return NULL;

	entry->mode = mode;
	entry->size = size;
	if(size > 0) {

		entry->data = (unsigned char *)malloc(size);
		if(entry->data == NULL) {

			free(entry);
			return NULL;
		
}
		memcpy(entry->data, data, size);
	
}
	entry->bstream = NULL;
	entry->next = NULL;

	return entry;

}

static void QRinput_List_freeEntry(QRinput_List *entry)
{

	if(entry != NULL) {

		free(entry->data);
		BitStream_free(entry->bstream);
		free(entry);
	
}

}

static QRinput_List *QRinput_List_dup(QRinput_List *entry)
{

	QRinput_List *n;

	n = (QRinput_List *)malloc(sizeof(QRinput_List));
	if(n == NULL) return NULL;

	n->mode = entry->mode;
	n->size = entry->size;
	n->data = (unsigned char *)malloc(n->size);
	if(n->data == NULL) {

		free(n);
		return NULL;
	
}
	memcpy(n->data, entry->data, entry->size);
	n->bstream = NULL;
	n->next = NULL;

	return n;

}

/******************************************************************************
 * Input Data
 *****************************************************************************/

QRinput *QRinput_new(void)
{

	return QRinput_new2(0, QR_ECLEVEL_L);

}

QRinput *QRinput_new2(int version, QRecLevel level)
{

	QRinput *input;

	if(version < 0 || version > QRSPEC_VERSION_MAX || level > QR_ECLEVEL_H) {

		errno = EINVAL;
		return NULL;
	
}

	input = (QRinput *)malloc(sizeof(QRinput));
	if(input == NULL) return NULL;

	input->head = NULL;
	input->tail = NULL;
	input->version = version;
	input->level = level;
	input->mqr = 0;
	input->fnc1 = 0;

	return input;

}

QRinput *QRinput_newMQR(int version, QRecLevel level)
{

	QRinput *input;

	if(version <= 0 || version > MQRSPEC_VERSION_MAX) goto INVALID;
	if((MQRspec_getECCLength(version, level) == 0)) goto INVALID;

	input = QRinput_new2(version, level);
	if(input == NULL) return NULL;

	input->mqr = 1;

	return input;

INVALID:
	errno = EINVAL;
	return NULL;

}

int QRinput_getVersion(QRinput *input)
{

	return input->version;

}

int QRinput_setVersion(QRinput *input, int version)
{

	if(input->mqr || version < 0 || version > QRSPEC_VERSION_MAX) {

		errno = EINVAL;
		return -1;
	
}

	input->version = version;

	return 0;

}

QRecLevel QRinput_getErrorCorrectionLevel(QRinput *input)
{

	return input->level;

}

int QRinput_setErrorCorrectionLevel(QRinput *input, QRecLevel level)
{

	if(input->mqr || level > QR_ECLEVEL_H) {

		errno = EINVAL;
		return -1;
	
}

	input->level = level;

	return 0;

}

int QRinput_setVersionAndErrorCorrectionLevel(QRinput *input, int version, QRecLevel level)
{

	if(input->mqr) {

		if(version <= 0 || version > MQRSPEC_VERSION_MAX) goto INVALID;
		if((MQRspec_getECCLength(version, level) == 0)) goto INVALID;
	
} else {

		if(version < 0 || version > QRSPEC_VERSION_MAX) goto INVALID;
		if(level > QR_ECLEVEL_H) goto INVALID;
	
}

	input->version = version;
	input->level = level;

	return 0;

INVALID:
	errno = EINVAL;
	return -1;

}

static void QRinput_appendEntry(QRinput *input, QRinput_List *entry)
{

	if(input->tail == NULL) {

		input->head = entry;
		input->tail = entry;
	
} else {

		input->tail->next = entry;
		input->tail = entry;
	
}
	entry->next = NULL;

}

int QRinput_append(QRinput *input, QRencodeMode mode, int size, const unsigned char *data)
{

	QRinput_List *entry;

	entry = QRinput_List_newEntry(mode, size, data);
	if(entry == NULL) {

		return -1;
	
}

	QRinput_appendEntry(input, entry);

	return 0;

}

/**
 * Insert a structured-append header to the head of the input data.
 * @param input input data.
 * @param size number of structured symbols.
 * @param index index number of the symbol. (1 <= index <= size)
 * @param parity parity among input data. (NOTE: each symbol of a set of structured symbols has the same parity data)
 * @retval 0 success.
 * @retval -1 error occurred and errno is set to indeicate the error. See Execptions for the details.
 * @throw EINVAL invalid parameter.
 * @throw ENOMEM unable to allocate memory.
 */
__STATIC int QRinput_insertStructuredAppendHeader(QRinput *input, int size, int index, unsigned char parity)
{

	QRinput_List *entry;
	unsigned char buf[3];

	if(size > MAX_STRUCTURED_SYMBOLS) {

		errno = EINVAL;
		return -1;
	
}
	if(index <= 0 || index > MAX_STRUCTURED_SYMBOLS) {

		errno = EINVAL;
		return -1;
	
}

	buf[0] = (unsigned char)size;
	buf[1] = (unsigned char)index;
	buf[2] = parity;
	entry = QRinput_List_newEntry(QR_MODE_STRUCTURE, 3, buf);
	if(entry == NULL) {

		return -1;
	
}

	entry->next = input->head;
	input->head = entry;

	return 0;

}

int QRinput_appendECIheader(QRinput *input, unsigned int ecinum)
{

	unsigned char data[4];

	if(ecinum > 999999) {

		errno = EINVAL;
		return -1;
	
}

	/* We manually create byte array of ecinum because
	 (unsigned char *)&ecinum may cause bus error on some architectures, */
	data[0] = ecinum & 0xff;
	data[1] = (ecinum >>  8) & 0xff;
	data[2] = (ecinum >> 16) & 0xff;
	data[3] = (ecinum >> 24) & 0xff;
	return QRinput_append(input, QR_MODE_ECI, 4, data);

}

void QRinput_free(QRinput *input)
{

	QRinput_List *list, *next;

	if(input != NULL) {

		list = input->head;
		while(list != NULL) {

			next = list->next;
			QRinput_List_freeEntry(list);
			list = next;
		
}
		free(input);
	
}

}

static unsigned char QRinput_calcParity(QRinput *input)
{

	unsigned char parity = 0;
	QRinput_List *list;
	int i;

	list = input->head;
	while(list != NULL) {

		if(list->mode != QR_MODE_STRUCTURE) {

			for(i=list->size-1; i>=0; i--) {

				parity ^= list->data[i];
			
}
		
}
		list = list->next;
	
}

	return parity;

}

QRinput *QRinput_dup(QRinput *input)
{

	QRinput *n;
	QRinput_List *list, *e;

	if(input->mqr) {

		n = QRinput_newMQR(input->version, input->level);
	
} else {

		n = QRinput_new2(input->version, input->level);
	
}
	if(n == NULL) return NULL;

	list = input->head;
	while(list != NULL) {

		e = QRinput_List_dup(list);
		if(e == NULL) {

			QRinput_free(n);
			return NULL;
		
}
		QRinput_appendEntry(n, e);
		list = list->next;
	
}

	return n;

}

/******************************************************************************
 * Numeric data
 *****************************************************************************/

/**
 * Check the input data.
 * @param size
 * @param data
 * @return result
 */
static int QRinput_checkModeNum(int size, const char *data)
{

	int i;

	for(i=0; i<size; i++) {

		if(data[i] < '0' || data[i] > '9')
			return -1;
	
}

	return 0;

}

/**
 * Estimates the length of the encoded bit stream of numeric data.
 * @param size
 * @return number of bits
 */
int QRinput_estimateBitsModeNum(int size)
{

	int w;
	int bits;

	w = size / 3;
	bits = w * 10;
	switch(size - w * 3) {

		case 1:
			bits += 4;
			break;
		case 2:
			bits += 7;
			break;
		default:
			break;
	
}

	return bits;

}

/**
 * Convert the number data to a bit stream.
 * @param entry
 * @param mqr
 * @retval 0 success
 * @retval -1 an error occurred and errno is set to indeicate the error.
 *            See Execptions for the details.
 * @throw ENOMEM unable to allocate memory.
 */
static int QRinput_encodeModeNum(QRinput_List *entry, int version, int mqr)
{

	int words, i, ret;
	unsigned int val;

	entry->bstream = BitStream_new();
	if(entry->bstream == NULL) return -1;

	if(mqr) {

		if(version > 1) {

			ret = BitStream_appendNum(entry->bstream, version - 1, MQRSPEC_MODEID_NUM);
			if(ret < 0) goto ABORT;
		
}
		ret = BitStream_appendNum(entry->bstream, MQRspec_lengthIndicator(QR_MODE_NUM, version), entry->size);
		if(ret < 0) goto ABORT;
	
} else {

		ret = BitStream_appendNum(entry->bstream, 4, QRSPEC_MODEID_NUM);
		if(ret < 0) goto ABORT;
	
		ret = BitStream_appendNum(entry->bstream, QRspec_lengthIndicator(QR_MODE_NUM, version), entry->size);
		if(ret < 0) goto ABORT;
	
}

	words = entry->size / 3;
	for(i=0; i<words; i++) {

		val  = (entry->data[i*3  ] - '0') * 100;
		val += (entry->data[i*3+1] - '0') * 10;
		val += (entry->data[i*3+2] - '0');

		ret = BitStream_appendNum(entry->bstream, 10, val);
		if(ret < 0) goto ABORT;
	
}

	if(entry->size - words * 3 == 1) {

		val = entry->data[words*3] - '0';
		ret = BitStream_appendNum(entry->bstream, 4, val);
		if(ret < 0) goto ABORT;
	
} else if(entry->size - words * 3 == 2) {

		val  = (entry->data[words*3  ] - '0') * 10;
		val += (entry->data[words*3+1] - '0');
		BitStream_appendNum(entry->bstream, 7, val);
		if(ret < 0) goto ABORT;
	
}

	return 0;
ABORT:
	BitStream_free(entry->bstream);
	entry->bstream = NULL;
	return -1;

}

/******************************************************************************
 * Alphabet-numer
...
...
(Not finished, please download and read the complete file)
			
...
Expand> <Close

Want complete source code? Download it here

Point(s): 3

Download
0 lines left, continue to read
Sponsored links

File list

Tips: You can preview the content of files by clicking file names^_^
Name Size Date
01.97 kB
01.97 kB
QRGenerator.ilk366.95 kB2013-06-11|12:21
01.97 kB
01.97 kB
BuildLog.htm15.69 kB2013-06-11|12:21
01.97 kB
bitstream.c4.21 kB2013-05-15|12:07
bitstream.h1.40 kB2013-05-15|12:07
config.h230.00 B2013-05-15|12:07
mask.c6.79 kB2013-05-15|12:07
mask.h1.52 kB2013-05-15|12:07
mmask.c4.01 kB2013-05-15|12:07
mmask.h1.37 kB2013-05-15|12:07
mqrspec.c6.92 kB2013-05-15|12:07
mqrspec.h4.66 kB2013-05-15|12:07
qrenc.c21.53 kB2013-06-05|16:59
qrencode.c19.60 kB2013-05-15|12:07
qrencode.h20.17 kB2013-05-15|12:07
qrencode_inner.h2.71 kB2013-05-15|12:07
qrinput.c38.05 kB2013-05-15|12:07
qrinput.h3.57 kB2013-05-15|12:07
qrspec.c15.35 kB2013-05-15|12:07
qrspec.h5.70 kB2013-05-15|12:07
rscode.c8.96 kB2013-05-15|12:07
rscode.h1.43 kB2013-05-15|12:07
split.c7.20 kB2013-05-15|12:07
split.h1.87 kB2013-05-15|12:07
QRGenerator.cpp6.14 kB2013-05-15|12:07
QRGenerator.vcproj5.68 kB2013-06-11|12:20
QRGenerator.vcproj.NCC1701A.TWOTM.user1.39 kB2013-06-11|12:21
QRGenerator.vcproj.PROXIMA.TWOTM.user1.38 kB2013-05-15|12:07
01.97 kB
bitstream.obj15.25 kB2013-06-11|12:21
BuildLog.htm10.58 kB2013-06-11|12:21
mask.obj19.98 kB2013-06-11|12:21
mmask.obj12.95 kB2013-06-11|12:21
mqrspec.obj16.01 kB2013-06-11|12:21
mt.dep62.00 B2013-06-11|12:21
qrencode.obj40.71 kB2013-06-11|12:21
QRGenerator.exe.intermediate.manifest616.00 B2013-06-11|12:21
QRGenerator.obj34.64 kB2013-06-11|12:21
qrinput.obj62.77 kB2013-06-11|12:21
qrspec.obj26.07 kB2013-06-11|12:21
rscode.obj14.36 kB2013-06-11|12:21
split.obj16.79 kB2013-06-11|12:21
stdafx.obj25.93 kB2013-06-11|12:21
vc90.idb83.00 kB2013-06-11|12:21
vc90.pdb76.00 kB2013-06-11|12:21
stdafx.cpp298.00 B2013-05-15|12:07
stdafx.h320.00 B2013-05-15|12:07
targetver.h765.00 B2013-05-15|12:07
QRGenerator.ncb683.00 kB2013-06-11|12:21
QRGenerator.sln899.00 B2013-05-15|12:07
QRGenerator.suo23.00 kB2013-06-11|12:21
01.97 kB
QRGenerator.exe28.00 kB2013-06-11|12:21
QRGenerator.pdb267.00 kB2013-06-11|12:21
...
Sponsored links

qrinput.c (497.86 kB)

Need 3 point
Your Point(s)

Your Point isn't enough.

Get point immediately by PayPal

More(Debit card / Credit card / PayPal Credit / Online Banking)

Submit your source codes. Get more point

LOGIN

Don't have an account? Register now
Need any help?
Mail to: support@codeforge.com

切换到中文版?

CodeForge Chinese Version
CodeForge English Version

Where are you going?

^_^"Oops ...

Sorry!This guy is mysterious, its blog hasn't been opened, try another, please!
OK

Warm tip!

CodeForge to FavoriteFavorite by Ctrl+D