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

📄 pdf417lib.c

📁 我论文里用到的预处理的一些程序
💻 C
📖 第 1 页 / 共 2 页
字号:
	for (ni = start; ni < length; ++ni)
	{
        // 乘以10
        for (k = retLast; k >= 0; --k)
            ret[k] *= 10;
        // 加上该数字
        ret[retLast] += text[ni] - '0';
        // 传播
        for (k = retLast; k > 0; --k) {
            ret[k - 1] += ret[k] / 900;
            ret[k] %= 900;
        }
    }
}

/******************************************************************************
 * 数字压缩
******************************************************************************/
void numberCompaction(pPdf417class p, int start, int length) 
{
    int full = (length / 44) * 15;
    int size = length % 44;
    int k;
    if (size == 0)
        size = full;
    else
        size = full + size / 3 + 1;
    
	if (size + p->cwPtr > MAX_DATA_CODEWORDS)
	{
        p->param->error = PDF417_ERROR_TEXT_TOO_BIG;
        return;
    }
    
	length += start;
    for (k = start; k < length; k += 44)
	{
        size = length - k < 44 ? length - k : 44;
        basicNumberCompaction(p, k, size);
    }
}

/******************************************************************************
 * 字节压缩6
******************************************************************************/
static void byteCompaction6(pPdf417class p, int start) 
{
    int length = 6;
    char* text = p->param->text;
    int* ret = p->param->codewords + p->cwPtr;
    int retLast = 4;
    int ni, k;
    p->cwPtr += retLast + 1;
    memset(ret, 0, (retLast + 1) * sizeof(int));
    length += start;
    
	for (ni = start; ni < length; ++ni) 
	{
        // 乘以256
        for (k = retLast; k >= 0; --k)
            ret[k] *= 256;
        // 加上该数字
        ret[retLast] += (int)text[ni] & 0xff;
        // 传播
        for (k = retLast; k > 0; --k)
		{
            ret[k - 1] += ret[k] / 900;
            ret[k] %= 900;
        }
    }
}

/******************************************************************************
 * 字节压缩
******************************************************************************/
void byteCompaction(pPdf417class p, int start, int length)
{
    int k, j;
    int size = (length / 6) * 5 + (length % 6);
    
	if (size + p->cwPtr > MAX_DATA_CODEWORDS)
	{
        p->param->error = PDF417_ERROR_TEXT_TOO_BIG;
        return;
    }
    
	length += start;
    for (k = start; k < length; k += 6)
	{
        size = length - k < 44 ? length - k : 6;
        if (size < 6)
		{
            for (j = 0; j < size; ++j)
                p->param->codewords[p->cwPtr++] = (int)p->param->text[k + j] & 0xff;
        }
        else
		{
            byteCompaction6(p, k);
        }
    }
}

/******************************************************************************
 * 中断文本
******************************************************************************/
void breakString(pPdf417class p, pArrayList list)
{
    char* text = p->param->text;
    int textLength = p->param->lenText;
    int lastP = 0;
    int startN = 0;
    int nd = 0;
    char c = 0;
    int k, ptrS, lastTxt, j, txt;
    pListElement v;
    pListElement vp;
    pListElement vn;
    list->size = 0;
    
	for (k = 0; k < textLength; ++k)
	{
        c = text[k];
        
		if (c >= '0' && c <= '9')
		{
            if (nd == 0)
                startN = k;
            ++nd;
            continue;
        }
        
		if (nd >= 13)
		{
            if (lastP != startN)
			{
                c = text[lastP];
                ptrS = lastP;
                lastTxt = (c >= ' ' && c < 127) || c == '\r' 
					|| c == '\n' || c == '\t';
               
				for (j = lastP; j < startN; ++j)
				{
                    c = text[j];
                    txt = (c >= ' ' && c < 127) || c == '\r' 
						|| c == '\n' || c == '\t';
                    
					if (txt != lastTxt)
					{
                        listAdd(list, (char)(lastTxt ? 'T' : 'B'), lastP, j);
                        lastP = j;
                        lastTxt = txt;
                    }
                }
                listAdd(list, (char)(lastTxt ? 'T' : 'B'), lastP, startN);
            }
            
			listAdd(list, 'N', startN, k);
            lastP = k;
        }
        nd = 0;
    }
   
	if (nd < 13)
        startN = textLength;
    
	if (lastP != startN)
	{
        c = text[lastP];
        ptrS = lastP;
        lastTxt = (c >= ' ' && c < 127) || c == '\r' || c == '\n' || c == '\t';
        
		for (j = lastP; j < startN; ++j)
		{
            c = text[j];
            txt = (c >= ' ' && c < 127) || c == '\r' || c == '\n' || c == '\t';
            
			if (txt != lastTxt)
			{
                listAdd(list, (char)(lastTxt ? 'T' : 'B'), lastP, j);
                lastP = j;
                lastTxt = txt;
            }
        }
        listAdd(list, (char)(lastTxt ? 'T' : 'B'), lastP, startN);
    }
    
	if (nd >= 13)
        listAdd(list, 'N', startN, textLength);
   
	// 优化,合并短的字节
    for (k = 0; k < list->size; ++k) 
	{
        v = listGet(list, k);
        vp = listGet(list, k - 1);
        vn = listGet(list, k + 1);;
        
		if (checkElementType(v, 'B') && getElementLength(v) == 1) 
		{
            if (checkElementType(vp, 'T') && checkElementType(vn, 'T') 
                && getElementLength(vp) + getElementLength(vn) >= 3) 
			{
                vp->end = vn->end;
                listRemove(list, k);
                listRemove(list, k);
                k = -1;
                continue;
            }
        }
    }
    
	// 合并文本区段
    for (k = 0; k < list->size; ++k) 
	{
        v = listGet(list, k);
        vp = listGet(list, k - 1);
        vn = listGet(list, k + 1);;
        
		if (checkElementType(v, 'T') && getElementLength(v) >= 5) 
		{
            int redo = 0;
            
			if ((checkElementType(vp, 'B') && getElementLength(vp) == 1) 
				|| checkElementType(vp, 'T')) 
			{
                redo = 1;
                v->start = vp->start;
                listRemove(list, k - 1);
                --k;
            }
            
			if ((checkElementType(vn, 'B') && getElementLength(vn) == 1) 
				|| checkElementType(vn, 'T')) 
			{
                redo = 1;
                v->end = vn->end;
                listRemove(list, k + 1);
            }
            
			if (redo) 
			{
                k = -1;
                continue;
            }
        }
    }
    
	// 合并二值区段
    for (k = 0; k < list->size; ++k) 
	{
        v = listGet(list, k);
        vp = listGet(list, k - 1);
        vn = listGet(list, k + 1);;
        
		if (checkElementType(v, 'B')) 
		{
            int redo = 0;
            
			if ((checkElementType(vp, 'T') && getElementLength(vp) < 5) 
				|| checkElementType(vp, 'B')) 
			{
                redo = 1;
                v->start = vp->start;
                listRemove(list, k - 1);
                --k;
            }
            
			if ((checkElementType(vn, 'T') && getElementLength(vn) < 5) 
				|| checkElementType(vn, 'B')) 
			{
                redo = 1;
                v->end = vn->end;
                listRemove(list, k + 1);
            }
            
			if (redo) 
			{
                k = -1;
                continue;
            }
        }
    }
    
	// 检查所有数字
    if (list->size == 1 && (v = listGet(list, 0))->type == 'T' 
		&& getElementLength(v) >= 8) 
	{
        for (k = v->start; k < v->end; ++k) 
		{
            c = text[k];
            if (c < '0' || c > '9')
                break;
        }
        if (k == v->end)
            v->type = 'N';
    }
}

/******************************************************************************
 * 汇编
******************************************************************************/
void assemble(pPdf417class p, pArrayList list)
{
    int k;
    if (list->size == 0)
        return;
    p->cwPtr = 1;
    
	for (k = 0; k < list->size; ++k) 
	{
        pListElement v = listGet(list, k);
        switch (v->type) 
		{
        case 'T':
            if (k != 0)
                p->param->codewords[p->cwPtr++] = TEXT_MODE;
            textCompaction(p, v->start, v->end - v->start);
            break;
        case 'N':
            p->param->codewords[p->cwPtr++] = NUMERIC_MODE;
            numberCompaction(p, v->start, v->end - v->start);
            break;
        case 'B':
            p->param->codewords[p->cwPtr++] 
				= (v->end - v->start) % 6 ? BYTE_MODE : BYTE_MODE_6;
            byteCompaction(p, v->start, v->end - v->start);
            break;
        }
        if (p->param->error)
            return;
    }
}
 
/******************************************************************************
 * 最大可能的纠错级别
******************************************************************************/
static int maxPossibleErrorLevel(int remain)
{
    int level = 8;
    int size = 512;
    
	while (level > 0)
	{
        if (remain >= size)
            return level;
        --level;
        size >>= 1;
    }
    
	return 0;
}

/******************************************************************************
 * 废弃链表
******************************************************************************/
void dumpList(pPdf417class p, pArrayList list) 
{
    int k;
    
	if (list->size == 0)
        return;
    
	for (k = 0; k < list->size; ++k) 
	{
        pListElement v = listGet(list, k);
        printf("%c%.*s\n", v->type, v->end - v->start, p->param->text + v->start);
    }
}

/******************************************************************************
 * 获得最大平方
******************************************************************************/
static int getMaxSquare(pPdf417param p) 
{
    if (p->codeColumns > 21) 
	{
        p->codeColumns = 29;
        p->codeRows = 32;
    }
    else 
	{
        p->codeColumns = 16;
        p->codeRows = 58;
    }
    return MAX_DATA_CODEWORDS + 2;
}

/******************************************************************************
 * 画出条形码
******************************************************************************/
void paintCode(pPdf417param p) 
{
    pdf417class pp;
    arrayList list;
    int maxErr, fixedColumn, lenErr, tot, skipRowColAdjust, pad;
    pp.param = p;
    p->error = 0;
    
	if (p->options & PDF417_USE_RAW_CODEWORDS) 
	{
        if (p->lenCodewords > MAX_DATA_CODEWORDS || p->lenCodewords < 1 
			|| p->lenCodewords != p->codewords[0]) 
		{
            p->error = PDF417_ERROR_INVALID_PARAMS;
            return;
        }
    }
    else 
	{
        if (p->lenText < 0)
            p->lenText = strlen(p->text);
        if (p->lenText > ABSOLUTE_MAX_TEXT_SIZE) 
		{
            p->error = PDF417_ERROR_TEXT_TOO_BIG;
            return;
        }
        listInit(&list);
        breakString(&pp, &list);
        dumpList(&pp, &list);
        assemble(&pp, &list);
        listFree(&list);
        if (p->error)
            return;
        p->codewords[0] = p->lenCodewords = pp.cwPtr;
    }
    
	maxErr = maxPossibleErrorLevel(MAX_DATA_CODEWORDS + 2 - p->lenCodewords);
    if (!(p->options & PDF417_USE_ERROR_LEVEL)) 
	{
        if (p->lenCodewords < 41)
            p->errorLevel = 2;
        else if (p->lenCodewords < 161)
            p->errorLevel = 3;
        else if (p->lenCodewords < 321)
            p->errorLevel = 4;
        else
            p->errorLevel = 5;
    }
    
	if (p->errorLevel < 0)
        p->errorLevel = 0;
    else if (p->errorLevel > maxErr)
        p->errorLevel = maxErr;
    if (p->codeColumns < 1)
        p->codeColumns = 1;
    else if (p->codeColumns > 30)
        p->codeColumns = 30;
    if (p->codeRows < 3)
        p->codeRows = 3;
    else if (p->codeRows > 90)
        p->codeRows = 90;
    
	lenErr = 2 << p->errorLevel;
    fixedColumn = !(p->options & PDF417_FIXED_ROWS);
    skipRowColAdjust = 0;
    tot = p->lenCodewords + lenErr;
    
	if (p->options & PDF417_FIXED_RECTANGLE) 
	{
        tot = p->codeColumns * p->codeRows;
        if (tot > MAX_DATA_CODEWORDS + 2) 
		{
            tot = getMaxSquare(p);
        }
        if (tot < p->lenCodewords + lenErr)
            tot = p->lenCodewords + lenErr;
        else
            skipRowColAdjust = 1;
    }
    else if (!(p->options & (PDF417_FIXED_COLUMNS | PDF417_FIXED_ROWS))) 
	{
        double c, b;
        fixedColumn = 1;
        if (p->aspectRatio < 0.001)
            p->aspectRatio = 0.001f;
        else if (p->aspectRatio > 1000)
            p->aspectRatio = 1000;
        b = 73 * p->aspectRatio - 4;
        c = (-b + sqrt(b * b + 4 * 17 * p->aspectRatio 
			* (p->lenCodewords + lenErr) * p->yHeight)) / (2 * 17 * p->aspectRatio);
        p->codeColumns = (int)(c + 0.5);
        if (p->codeColumns < 1)
            p->codeColumns = 1;
        else if (p->codeColumns > 30)
            p->codeColumns = 30;
    }
    
	if (!skipRowColAdjust) 
	{
        if (fixedColumn)
		{
            p->codeRows = (tot - 1) / p->codeColumns + 1;
            if (p->codeRows < 3)
                p->codeRows = 3;
            else if (p->codeRows > 90) 
			{
                p->codeRows = 90;
                p->codeColumns = (tot - 1) / 90 + 1;
            }
        }
        else 
		{
            p->codeColumns = (tot - 1) / p->codeRows + 1;
            if (p->codeColumns > 30) 
			{
                p->codeColumns = 30;
                p->codeRows = (tot - 1) / 30 + 1;
            }
        }
        tot = p->codeRows * p->codeColumns;
    }
    
	if (tot > MAX_DATA_CODEWORDS + 2) 
	{
        tot = getMaxSquare(p);
    }
    
	p->errorLevel = maxPossibleErrorLevel(tot - p->lenCodewords);
    lenErr = 2 << p->errorLevel;
    pad = tot - lenErr - p->lenCodewords;
    pp.cwPtr = p->lenCodewords;
    while (pad--)
        p->codewords[pp.cwPtr++] = TEXT_MODE;
    p->codewords[0] = p->lenCodewords = pp.cwPtr;
    calculateErrorCorrection(&pp, pp.param->lenCodewords);
    pp.param->lenCodewords = tot;
    outPaintCode(&pp);
}

⌨️ 快捷键说明

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