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

📄 pdf417lib.c

📁 我论文里用到的预处理的一些程序
💻 C
📖 第 1 页 / 共 2 页
字号:
/******************************************************************************
 * 文件名:pdf417lib.c
 * 功能  :条形码操作函数库
 * modified by PRTsinghua@hotmail.com
******************************************************************************/

#include <malloc.h>
#include <string.h>
#include <stdio.h>
#include <math.h>
#define __INCLUDE_PDF417LIBIMP_H__
#include "pdf417libimp.h"
#undef __INCLUDE_PDF417LIBIMP_H__
#include "pdf417lib.h"

#ifndef NULL
#ifdef  __cplusplus
#define NULL    0
#else
#define NULL    ((void *)0)
#endif
#endif

char* MIXED_SET = "0123456789&\r\t,:#-.$/+%*=^";
char* PUNCTUATION_SET = ";<>@[\\]_`~!\r\t,:\n-.$/\"|*()?{}'";

// 线性表元素结构定义
typedef struct _listElement
{
    char type;
    int start;
    int end;
} listElement, *pListElement;

// 线性表结果定义
typedef struct _arrayList {
    pListElement array;
    int size;
    int capacity;
} arrayList, *pArrayList;

typedef struct _pdf417class {
    int bitPtr;
    int cwPtr;
    pdf417param *param;
} pdf417class, *pPdf417class;


/******************************************************************************
 * 初始化线性表
******************************************************************************/
void listInit(pArrayList list)
{
    list->capacity = 20;
    list->size = 0;
    list->array = (pListElement)malloc(list->capacity * sizeof(listElement));
}

/******************************************************************************
 * 释放线性表
******************************************************************************/
void listFree(pArrayList list) 
{
    free(list->array);
    list->array = NULL;
}

/******************************************************************************
 * 给线性表增加一个元素
******************************************************************************/
void listAdd(pArrayList list, char type, int start, int end)
{
    if (list->size == list->capacity) 
	{
        pListElement temp;
        list->capacity *= 2;
        temp = (pListElement)malloc(list->capacity * sizeof(listElement));
        memcpy(temp, list->array, list->size * sizeof(listElement));
        free(list->array);
        list->array = temp;
    }
    list->array[list->size].type = type;
    list->array[list->size].start = start;
    list->array[list->size].end = end;
    ++list->size;
}

/******************************************************************************
 * 获得线性表某个位置的元素
******************************************************************************/
pListElement listGet(pArrayList list, int idx) 
{
    if (idx >= list->size || idx < 0)
        return NULL;
    return list->array + idx;
}

/******************************************************************************
 * 删除线性表中某个元素
******************************************************************************/
void listRemove(pArrayList list, int idx) 
{
    if (idx >= list->size || idx < 0)
        return;
    --list->size;
    memmove(list->array + idx, list->array + (idx + 1), 
		(list->size - idx) * sizeof(listElement));
}

/******************************************************************************
 * 检查线性表元素类型
******************************************************************************/
int checkElementType(pListElement p, char type)
{
    if (!p)
        return 0;
    return (p->type == type);
}

/******************************************************************************
 * 求取线性表元素长度
******************************************************************************/
int getElementLength(pListElement p) 
{
    if (!p)
        return 0;
    return p->end - p->start;
}

/******************************************************************************
 * 初始化二维条形码结构
******************************************************************************/
void pdf417init(pPdf417param param) 
{
    param->options = 0;
    param->outBits = NULL;
    param->lenBits = 0;
    param->error = 0;
    param->lenText = -1;
    param->text = "";
    param->yHeight = 3;
    param->aspectRatio = 0.5;
}

/******************************************************************************
 * 释放二维挑衅伽马结果
******************************************************************************/
void pdf417free(pPdf417param param) 
{
    if (param->outBits != NULL) 
	{
        free(param->outBits);
        param->outBits = NULL;
    }
}

/******************************************************************************
 * 输出宽度位17的码字
******************************************************************************/
void outCodeword17(pPdf417class p, int codeword) 
{
    int bytePtr = p->bitPtr / 8;
    int bit = p->bitPtr - bytePtr * 8;
    p->param->outBits[bytePtr++] |= codeword >> (9 + bit);
    p->param->outBits[bytePtr++] |= codeword >> (1 + bit);
    codeword <<= 8;
    p->param->outBits[bytePtr] |= codeword >> (1 + bit);
    p->bitPtr += 17;
}

/******************************************************************************
 * 输出宽度为18的码字
******************************************************************************/
void outCodeword18(pPdf417class p, int codeword) 
{
    int bytePtr = p->bitPtr / 8;
    int bit = p->bitPtr - bytePtr * 8;
    p->param->outBits[bytePtr++] |= codeword >> (10 + bit);
    p->param->outBits[bytePtr++] |= codeword >> (2 + bit);
    codeword <<= 8;
    p->param->outBits[bytePtr] |= codeword >> (2 + bit);
    if (bit == 7)
        p->param->outBits[++bytePtr] |= 0x80;
    p->bitPtr += 18;
}

/******************************************************************************
 * 输出数据码字
******************************************************************************/
void outCodeword(pPdf417class p, int codeword) 
{
    outCodeword17(p, codeword);
}

/******************************************************************************
 * 输出结束模式
******************************************************************************/
void outStopPattern(pPdf417class p) 
{
    outCodeword18(p, STOP_PATTERN);
}

/******************************************************************************
 * 输出起始模式
******************************************************************************/
void outStartPattern(pPdf417class p) 
{
    outCodeword17(p, START_PATTERN);
}

/******************************************************************************
 * 输出码字
******************************************************************************/
void outPaintCode(pPdf417class p) 
{
    int codePtr = 0;
    int row;
    int rowMod;
    int *cluster;
    int edge;
    int column;
    
	p->param->bitColumns = START_CODE_SIZE * (p->param->codeColumns + 3) + STOP_SIZE;
    p->param->lenBits = ((p->param->bitColumns - 1) / 8 + 1) * p->param->codeRows;
    p->param->outBits = (char*)malloc(p->param->lenBits);
    memset(p->param->outBits, 0, p->param->lenBits);
    
	for (row = 0; row < p->param->codeRows; ++row) 
	{
        p->bitPtr = ((p->param->bitColumns - 1) / 8 + 1) * 8 * row;
        rowMod = row % 3;
        cluster = CLUSTERS[rowMod];
        outStartPattern(p);
        edge = 0;
        
		switch (rowMod) 
		{
        case 0:
            edge = 30 * (row / 3) + ((p->param->codeRows - 1) / 3);
            break;
        case 1:
            edge = 30 * (row / 3) + p->param->errorLevel * 3 + ((p->param->codeRows - 1) % 3);
            break;
        default:
            edge = 30 * (row / 3) + p->param->codeColumns - 1;
            break;
        }
        
		outCodeword(p, cluster[edge]);

        for (column = 0; column < p->param->codeColumns; ++column) 
		{
            outCodeword(p, cluster[p->param->codewords[codePtr++]]);
        }
        
        switch (rowMod) 
		{
        case 0:
            edge = 30 * (row / 3) + p->param->codeColumns - 1;
            break;
        case 1:
            edge = 30 * (row / 3) + ((p->param->codeRows - 1) / 3);
            break;
        default:
            edge = 30 * (row / 3) + p->param->errorLevel * 3 + ((p->param->codeRows - 1) % 3);
            break;
        }
        
		outCodeword(p, cluster[edge]);
        outStopPattern(p);
    }
    
	if (p->param->options & PDF417_INVERT_BITMAP) 
	{
        char* pm = p->param->outBits;
        char* end = pm + p->param->lenBits;
        while (pm < end)
            *(pm++) ^= 0xff;
    }
}

/******************************************************************************
 * 计算错误纠正码
******************************************************************************/
void calculateErrorCorrection(pPdf417class p, int dest) 
{
    int t1 = 0;
    int t2 = 0;
    int t3 = 0;
    int *A;
    int Alength;
    int *E;
    int lastE;
    int k, e, j;
    
	if (p->param->errorLevel < 0 || p->param->errorLevel > 8)
        p->param->errorLevel = 0;
    
	A = ERROR_LEVEL[p->param->errorLevel];
    Alength = 2 << p->param->errorLevel;
    E = p->param->codewords + dest;
    memset(E, 0, Alength * sizeof(int));
    lastE = Alength - 1;
    
	for (k = 0; k < p->param->lenCodewords; ++k) 
	{
        t1 = p->param->codewords[k] + E[0];
        for (e = 0; e <= lastE; ++e) 
		{
            t2 = (t1 * A[lastE - e]) % MOD;
            t3 = MOD - t2;
            E[e] = ((e == lastE ? 0 : E[e + 1]) + t3) % MOD;
        }
    }
    
	for (j = 0; j < Alength; ++j)
        E[j] = (MOD - E[j]) % MOD;
}

/******************************************************************************
 * 获得文本类型和数值
******************************************************************************/
static int getTextTypeAndValue(char* text, int size, int idx) 
{
    int c;
    char *ms, *ps;
    
	if (idx >= size)
        return 0;
    c = text[idx];
    if (c >= 'A' && c <= 'Z')
        return (ALPHA + c - 'A');
    if (c >= 'a' && c <= 'z')
        return (LOWER + c - 'a');
    if (c == ' ')
        return (ALPHA + LOWER + MIXED + SPACE);
    
	ms = strchr(MIXED_SET, c);
    ps = strchr(PUNCTUATION_SET, c);
    
	if (!ms && !ps)
        return (ISBYTE + (c & 0xff));
    if (ms - MIXED_SET == ps - PUNCTUATION_SET)
        return (MIXED + PUNCTUATION + (ms - MIXED_SET));
    if (ms != NULL)
        return (MIXED + (ms - MIXED_SET));
    
	return (PUNCTUATION + (ps - PUNCTUATION_SET));
}

/******************************************************************************
 * 文本压缩
******************************************************************************/
void textCompaction(pPdf417class p, int start, int length) 
{
    int dest[ABSOLUTE_MAX_TEXT_SIZE * 2];
    char* text = p->param->text;
    int mode = ALPHA;
    int ptr = 0;
    int fullBytes = 0;
    int v = 0;
    int k;
    int size;
    memset(dest, 0, sizeof(dest));
    length += start;
    
	for (k = start; k < length; ++k)
	{
        v = getTextTypeAndValue(text, length, k);
        
		if ((v & mode) != 0)
		{
            dest[ptr++] = v & 0xff;
            continue;
        }
        
		if ((v & ISBYTE) != 0)
		{
            if ((ptr & 1) != 0)
			{
                dest[ptr++] = (mode & PUNCTUATION) != 0 ? PAL : PS;
                mode = (mode & PUNCTUATION) != 0 ? ALPHA : mode;
            }
            
			dest[ptr++] = BYTESHIFT;
            dest[ptr++] = v & 0xff;
            fullBytes += 2;
            continue;
        }
        
		switch (mode) 
		{
        case ALPHA:
            if ((v & LOWER) != 0) 
			{
                dest[ptr++] = LL;
                dest[ptr++] = v & 0xff;
                mode = LOWER;
            }
            else if ((v & MIXED) != 0) 
			{
                dest[ptr++] = ML;
                dest[ptr++] = v & 0xff;
                mode = MIXED;
            }
            else if ((getTextTypeAndValue(text, length, k + 1) 
				& getTextTypeAndValue(text, length, k + 2) & PUNCTUATION) != 0) 
			{
                dest[ptr++] = ML;
                dest[ptr++] = PL;
                dest[ptr++] = v & 0xff;
                mode = PUNCTUATION;
            }
            else
			{
                dest[ptr++] = PS;
                dest[ptr++] = v & 0xff;
            }
            break;
        case LOWER:
            if ((v & ALPHA) != 0)
			{
                if ((getTextTypeAndValue(text, length, k + 1) 
					& getTextTypeAndValue(text, length, k + 2) & ALPHA) != 0) 
				{
                    dest[ptr++] = ML;
                    dest[ptr++] = AL;
                    mode = ALPHA;
                }
                else 
				{
                    dest[ptr++] = AS;
                }
                dest[ptr++] = v & 0xff;
            }
            else if ((v & MIXED) != 0)
			{
                dest[ptr++] = ML;
                dest[ptr++] = v & 0xff;
                mode = MIXED;
            }
            else if ((getTextTypeAndValue(text, length, k + 1) 
				& getTextTypeAndValue(text, length, k + 2) & PUNCTUATION) != 0) 
			{
                dest[ptr++] = ML;
                dest[ptr++] = PL;
                dest[ptr++] = v & 0xff;
                mode = PUNCTUATION;
            }
            else 
			{
                dest[ptr++] = PS;
                dest[ptr++] = v & 0xff;
            }
            break;
        case MIXED:
            if ((v & LOWER) != 0)
			{
                dest[ptr++] = LL;
                dest[ptr++] = v & 0xff;
                mode = LOWER;
            }
            else if ((v & ALPHA) != 0)
			{
                dest[ptr++] = AL;
                dest[ptr++] = v & 0xff;
                mode = ALPHA;
            }
            else if ((getTextTypeAndValue(text, length, k + 1) 
				& getTextTypeAndValue(text, length, k + 2) & PUNCTUATION) != 0)
			{
                dest[ptr++] = PL;
                dest[ptr++] = v & 0xff;
                mode = PUNCTUATION;
            }
            else
			{
                dest[ptr++] = PS;
                dest[ptr++] = v & 0xff;
            }
            break;
        case PUNCTUATION:
            dest[ptr++] = PAL;
            mode = ALPHA;
            --k;
            break;
        }
    }
    
	if ((ptr & 1) != 0)
        dest[ptr++] = PS;
    size = (ptr + fullBytes) / 2;
    if (size + p->cwPtr > MAX_DATA_CODEWORDS)
	{
        p->param->error = PDF417_ERROR_TEXT_TOO_BIG;
        return;
    }
    
	length = ptr;
    ptr = 0;
    while (ptr < length)
	{
        v = dest[ptr++];
        if (v >= 30)
		{
            p->param->codewords[p->cwPtr++] = v;
            p->param->codewords[p->cwPtr++] = dest[ptr++];
        }
        else
            p->param->codewords[p->cwPtr++] = v * 30 + dest[ptr++];
    }
}

/******************************************************************************
 * 基本数字的压缩
******************************************************************************/
static void basicNumberCompaction(pPdf417class p, int start, int length)
{
    char* text = p->param->text;
    int* ret = p->param->codewords + p->cwPtr;
    int retLast = length / 3;
    int ni, k;
    p->cwPtr += retLast + 1;
    memset(ret, 0, (retLast + 1) * sizeof(int));
    ret[retLast] = 1;
    length += start;
    

⌨️ 快捷键说明

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