⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 qrinput.c

📁 二维码QR的编码实现。C语言实现。希望各位一起学习。一起做条码开发
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * qrencode - QR Code encoder * * Input data chunk class * Copyright (C) 2006, 2007, 2008 Kentaro Fukuchi <fukuchi@megaui.net> * * 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 */#include <stdio.h>#include <stdlib.h>#include <string.h>#include <errno.h>#include "qrencode.h"#include "qrspec.h"#include "bitstream.h"#include "qrinput.h"/****************************************************************************** * 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;	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 QRinput_List *QRinput_List_freeEntry(QRinput_List *entry){	QRinput_List *next;	next = entry->next;	free(entry->data);	if(entry->bstream) {		BitStream_free(entry->bstream);	}	free(entry);	return next;}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_L || 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;	return input;}int QRinput_getVersion(QRinput *input){	return input->version;}int QRinput_setVersion(QRinput *input, int version){	if(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(level < QR_ECLEVEL_L || level > QR_ECLEVEL_H) {		errno = EINVAL;		return -1;	}	input->level = level;	return 0;}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;}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;}void QRinput_free(QRinput *input){	QRinput_List *list;	list = input->head;	while(list != NULL) {		list = QRinput_List_freeEntry(list);	}	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;	n = QRinput_new2(input->version, input->level);	if(n == NULL) return NULL;	list = input->head;	while(list != NULL) {		e = QRinput_List_dup(list);		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 */static void QRinput_encodeModeNum(QRinput_List *entry, int version){	int words;	int i;	unsigned int val;	words = entry->size / 3;	entry->bstream = BitStream_new();	val = 0x1;	BitStream_appendNum(entry->bstream, 4, val);		val = entry->size;	BitStream_appendNum(entry->bstream, QRspec_lengthIndicator(QR_MODE_NUM, version), val);	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');		BitStream_appendNum(entry->bstream, 10, val);	}	if(entry->size - words * 3 == 1) {		val = entry->data[words*3] - '0';		BitStream_appendNum(entry->bstream, 4, val);	} 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);	}}/****************************************************************************** * Alphabet-numeric data *****************************************************************************/const signed char QRinput_anTable[] = {	-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,	-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,	36, -1, -1, -1, 37, 38, -1, -1, -1, -1, 39, 40, -1, 41, 42, 43,	 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 44, -1, -1, -1, -1, -1,	-1, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,	25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, -1, -1, -1, -1, -1,	-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,	-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1};/** * Check the input data. * @param size * @param data * @return result */static int QRinput_checkModeAn(int size, const char *data){	int i;	for(i=0; i<size; i++) {		if(QRinput_lookAnTable(data[i]) < 0)			return -1;	}	return 0;}/** * Estimates the length of the encoded bit stream of alphabet-numeric data. * @param size * @return number of bits */int QRinput_estimateBitsModeAn(int size){	int w;	int bits;	w = size / 2;	bits = w * 11;	if(size & 1) {		bits += 6;	}	return bits;}/** * Convert the alphabet-numeric data to a bit stream. * @param entry */static void QRinput_encodeModeAn(QRinput_List *entry, int version){	int words;	int i;	unsigned int val;	words = entry->size / 2;	entry->bstream = BitStream_new();	val = 0x2;	BitStream_appendNum(entry->bstream, 4, val);		val = entry->size;	BitStream_appendNum(entry->bstream, QRspec_lengthIndicator(QR_MODE_AN, version), val);	for(i=0; i<words; i++) {		val  = (unsigned int)QRinput_lookAnTable(entry->data[i*2  ]) * 45;		val += (unsigned int)QRinput_lookAnTable(entry->data[i*2+1]);		BitStream_appendNum(entry->bstream, 11, val);	}	if(entry->size & 1) {		val = (unsigned int)QRinput_lookAnTable(entry->data[words * 2]);		BitStream_appendNum(entry->bstream, 6, val);	}}/****************************************************************************** * 8 bit data *****************************************************************************//** * Estimates the length of the encoded bit stream of 8 bit data. * @param size * @return number of bits */int QRinput_estimateBitsMode8(int size){	return size * 8;}/** * Convert the 8bits data to a bit stream. * @param entry */static void QRinput_encodeMode8(QRinput_List *entry, int version){	int i;	unsigned int val;	entry->bstream = BitStream_new();	val = 0x4;	BitStream_appendNum(entry->bstream, 4, val);		val = entry->size;	BitStream_appendNum(entry->bstream, QRspec_lengthIndicator(QR_MODE_8, version), val);	for(i=0; i<entry->size; i++) {		BitStream_appendNum(entry->bstream, 8, entry->data[i]);	}}/****************************************************************************** * Kanji data *****************************************************************************//** * Estimates the length of the encoded bit stream of kanji data. * @param size * @return number of bits */int QRinput_estimateBitsModeKanji(int size){	return (size / 2) * 13;}/** * Check the input data. * @param size * @param data * @return result */static int QRinput_checkModeKanji(int size, const unsigned char *data){	int i;	unsigned int val;	if(size & 1)		return -1;	for(i=0; i<size; i+=2) {		val = ((unsigned int)data[i] << 8) | data[i+1];		if(val < 0x8140 || (val > 0x9ffc && val < 0xe040) || val > 0xebbf) {			return -1;		}	}	return 0;}/** * Convert the kanji data to a bit stream. * @param entry */static void QRinput_encodeModeKanji(QRinput_List *entry, int version){	int i;	unsigned int val, h;	entry->bstream = BitStream_new();	val = 0x8;	BitStream_appendNum(entry->bstream, 4, val);		val = entry->size / 2;	BitStream_appendNum(entry->bstream, QRspec_lengthIndicator(QR_MODE_KANJI, version), val);	for(i=0; i<entry->size; i+=2) {		val = ((unsigned int)entry->data[i] << 8) | entry->data[i+1];		if(val <= 0x9ffc) {			val -= 0x8140;		} else {			val -= 0xc140;		}		h = (val >> 8) * 0xc0;		val = (val & 0xff) + h;		BitStream_appendNum(entry->bstream, 13, val);	}}/****************************************************************************** * Structured Symbol *****************************************************************************//** * Convert a structure symbol code to a bit stream. * @param entry */static void QRinput_encodeModeStructure(QRinput_List *entry, int version){	entry->bstream = BitStream_new();	BitStream_appendNum(entry->bstream, 4, 0x03);	BitStream_appendNum(entry->bstream, 4, entry->data[1] - 1);	BitStream_appendNum(entry->bstream, 4, entry->data[0] - 1);	BitStream_appendNum(entry->bstream, 8, entry->data[2]);}/****************************************************************************** * Validation *****************************************************************************/int QRinput_check(QRencodeMode mode, int size, const unsigned char *data){	if(size <= 0) return -1;	switch(mode) {		case QR_MODE_NUM:			return QRinput_checkModeNum(size, (const char *)data);			break;		case QR_MODE_AN:			return QRinput_checkModeAn(size, (const char *)data);			break;		case QR_MODE_KANJI:			return QRinput_checkModeKanji(size, data);			break;		case QR_MODE_8:			return 0;			break;		case QR_MODE_STRUCTURE:			return 0;			break;		default:			break;	}	return -1;}/****************************************************************************** * Estimation of the bit length *****************************************************************************//**

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -