From SwPatWiki

Main: PDF417

#include "types.h" /* Type definitions */ #include "global_refs.h" /* Globals that we must see */ #include "pdf417.h" #include "Codewrd0.h" #include "Codewrd3.h" #include "Codewrd6.h" #include "subchar.h" #include "errorlev.h" extern unsigned char adex_value; #define ERRBUFLEN 42 #define PADDING_WORD 900 #define MODE_TEXT_ALPHA 1 #define MODE_TEXT_LOWER 2 #define MODE_TEXT_MIXED 4 #define MODE_TEXT_PUNCT 8 #define MODE_NUMERIC 16 #define MODE_BYTE 32 #define MODE_BS 64 //const unsigned char *errbptr=(char *)&text_buff; //const PDFBUFF *pdfbuff=(PDFBUFF *)(((char*)&text_buff)+ERRBUFFLEN); const int errbptr=(int)&text_buff; const int pdfbufp=ERRBUFLEN+4+(int)&text_buff; /*FIXME 4 bytes*/ #define errbuff ((unsigned char *)errbptr) #define pdfbuff ((PDFBUFF *)pdfbufp) void mydeb_putc(unsigned char c) { putchar((((c)&0xf0)>>4)+'0'); putchar(((c)&0xf)+'0'); } void mydeb_puti(unsigned int i) { mydeb_putc(i>>8); mydeb_putc(i&0xff); } void crlf(){ putchar('\n'); putchar('\r'); } void print_stack() { unsigned char *ptrke; unsigned char *tmp; tmp=&adex_value; ptrke=tmp; tmp+=0x1f; crlf(); for(;ptrke<tmp;ptrke++) { mydeb_putc(*ptrke); } crlf(); } #define print_sp() //#define print_sp() mydeb_puti(_asm("tsx\n pshh\n pula")); void mydebug(char*ptr,unsigned char len) { for(;len>0;len--) { mydeb_putc(*ptr); ptr++; } crlf(); } /*-------------------------------------------------------*/ #define tmpvaruc0 (pdfbuff->tmp.uc[0]) #define tmpvaruc1 (pdfbuff->tmp.uc[1]) #define cols (pdfbuff->Cols) #define errlev (pdfbuff->Errlev) #define rows (pdfbuff->Rows) #define line (pdfbuff->Line) #define datalenke (pdfbuff->Datalen) #define mrfifo_data (pdfbuff->Data) #define mrfifo_len (pdfbuff->Len) #define mrfifo_oldmode (pdfbuff->Oldmode) #define mrfifo_datalen (pdfbuff->Fifolen) #define mrfifo_round (pdfbuff->Round) void mrfifo_init();/* does init for cv and output (err) as well */ void mrfifo_fill(); void mrfifo_shift(unsigned char count); unsigned char mrfifo_newmode(); #define cv_text_data (pdfbuff->Text_data) #define CV_NODATA 31 char cv_text_eat(); void cv_text_done(); void cv_text_start(unsigned char newmode); char cv_num_worth(); char cv_num_eat(); void cv_num_start(unsigned char newmode); /*void cv_num_done(); optimized out*/ char cv_byte_eat(); void cv_byte_start(unsigned char newmode); /*void cv_byte_done(); optimized out */ char cv_bs_eat(); void cv_bs_start(unsigned char newmode); /* void cv_bs_done(); optimized out */ #define output_prlen (pdfbuff->Prlen) void output_add(int codeword); void output_p_ercompute(int codeword); void output_p_print(int codeword); void math_num_prepare(char len); int math_div_num(char start,char len); int math_div_256(char len); void math_num_print(char len); #define panic(a) putchar('*');putchar(a); /*-------------------------------------------------------*/ void mrfifo_loop() { unsigned char newmode; while((mrfifo_datalen>0) || (mrfifo_len > 0 )) { mrfifo_fill(); newmode=mrfifo_newmode(); if(newmode != mrfifo_oldmode) { if((mrfifo_oldmode &0x0f)&&(!(newmode&0x0f))) /* it was text */ { cv_text_done(); } switch(newmode) { case MODE_TEXT_ALPHA: case MODE_TEXT_LOWER: case MODE_TEXT_MIXED: case MODE_TEXT_PUNCT: cv_text_start(newmode); break; case MODE_BYTE: cv_byte_start(newmode); break; case MODE_NUMERIC: cv_num_start(newmode); break; case MODE_BS: cv_bs_start(newmode); break; default: panic('A'); } } switch(newmode){ case MODE_TEXT_ALPHA: case MODE_TEXT_LOWER: case MODE_TEXT_MIXED: case MODE_TEXT_PUNCT: mrfifo_shift(cv_text_eat()); break; case MODE_BYTE: mrfifo_shift(cv_byte_eat()); break; case MODE_NUMERIC: mrfifo_shift(cv_num_eat()); break; case MODE_BS: mrfifo_shift(cv_bs_eat()); break; default: panic('B'); } } if(mrfifo_oldmode &0x0f) { cv_text_done(); } } void mrfifo_shift(unsigned char count) { unsigned char i; if(count>mrfifo_len) { panic('D'); } for(i=0;i<mrfifo_len-count;i++) { mrfifo_data[i]=mrfifo_data[i+count]; } mrfifo_len-=count; mrfifo_fill(); } void mrfifo_fill() { while((mrfifo_len < (MRFIFO_DATA_LEN-1)) && (mrfifo_datalen > 0)) { mrfifo_data[mrfifo_len]=getchar('a'); //putchar('f'); //mydeb_putc(mrfifo_data[mrfifo_len]); mrfifo_len++; mrfifo_datalen--; } } unsigned char mrfifo_p_onemode(unsigned char c) { unsigned char mode; unsigned char i; print_sp(); mode=0; if(('0' <= c ) && ( c <= '9')) { mode |= cv_num_worth(); } if((('A' <= c) && ( c <= 'Z')) || c == ' ') { mode|=MODE_TEXT_ALPHA; } if((('a' <= c) && ( c <= 'z')) || c == ' ') { mode|=MODE_TEXT_LOWER; } for(i=0;i<25;i++) { if(c==mixtab[i]) { mode |= MODE_TEXT_MIXED; break; } } for(i=0;i<29;i++) { if(c==puntab[i]) { mode |= MODE_TEXT_PUNCT; break; } } if(0==mode) { mode = MODE_BYTE; } return(mode); #undef mode #undef i } unsigned char mrfifo_newmode() { unsigned char i; unsigned char thismode; thismode=mrfifo_p_onemode(mrfifo_data[0]); if(thismode&MODE_NUMERIC) { return MODE_NUMERIC; } #define nextmode mrfifo_p_onemode(mrfifo_data[1]) if((mrfifo_oldmode&0xf)&&(nextmode&0xf)&&(thismode==MODE_BYTE)) { return MODE_BS; } if(thismode == MODE_BYTE) { return MODE_BYTE; } if(thismode&mrfifo_oldmode) { /* We could further optimize it, with nextmode, but won't */ return mrfifo_oldmode; } if(thismode&nextmode) { unsigned char mode=thismode&nextmode; /* It could be optimized by oldmode, and the precedencies*/ if(mode&MODE_TEXT_ALPHA) { return MODE_TEXT_ALPHA; } if(mode&MODE_TEXT_LOWER) { return MODE_TEXT_LOWER; } if(mode&MODE_TEXT_MIXED) { return MODE_TEXT_MIXED; } if(mode&MODE_TEXT_PUNCT) { return MODE_TEXT_PUNCT; } panic('E'); } for(i=0;thismode;i++) { thismode=thismode>>1; } thismode=1; thismode=thismode<<(i-1); return thismode; } void cv_text_p_eat(unsigned char c) { if(cv_text_data != CV_NODATA) { output_add(cv_text_data*30+c); cv_text_data = CV_NODATA; } else { cv_text_data = c; } } char cv_text_eat() { unsigned char i; switch(mrfifo_oldmode) { case MODE_TEXT_ALPHA: mrfifo_data[0]=mrfifo_data[0]-'A'; break; case MODE_TEXT_LOWER: mrfifo_data[0]-='a'; break; case MODE_TEXT_MIXED: for(i=0;i<25;i++) { if(mixtab[i]==mrfifo_data[0]) { mrfifo_data[0]=i; break; } } break; case MODE_TEXT_PUNCT: for(i=0;i<29;i++) { if(puntab[i]==mrfifo_data[0]) { mrfifo_data[0]=i; break; } } break; default: panic('F'); } cv_text_p_eat(mrfifo_data[0]); return 1; } void cv_text_done() { //putchar('D'); if(cv_text_data != CV_NODATA) { output_add(cv_text_data*30+29); if(mrfifo_oldmode == MODE_TEXT_PUNCT) { mrfifo_oldmode = MODE_TEXT_ALPHA; } /* it would be PS, but if byteshift follows, it is ignored, else it is not significant*/ } //putchar('d'); } void cv_text_start(unsigned char newmode) { unsigned char i,j; if(0 == (mrfifo_oldmode & 0xf )) /* it was not text mode */ { output_add(900); } else { unsigned char nm; i=0xff; j=0xff; nm=newmode; for(;newmode;newmode = newmode >> 1) { i++; } if(i>3) { panic('G'); } newmode=mrfifo_oldmode; for(;newmode;newmode = newmode >>1) { j++; } if(j>3) { panic('H'); } newmode=nm; nm=i*2+j*8; if(txt_jumptab[nm]) { cv_text_p_eat(txt_jumptab[nm]); if(txt_jumptab[nm+1]) { cv_text_p_eat(txt_jumptab[nm+1]); } } else { panic('I'); } } mrfifo_oldmode=newmode; } char cv_num_worth() { char i; for(i=0;i<mrfifo_len;i++) { if(('0' > mrfifo_data[i]) || (mrfifo_data[i] > '9')) { break; } } if(i>5) { return MODE_NUMERIC; } return 0; } char cv_num_eat() { char i; for(i=0;i<mrfifo_len;i++) { if(('0' > mrfifo_data[i]) || (mrfifo_data[i] > '9')) { break; } } math_num_print(i); return(i); } void cv_num_start(unsigned char newmode) { output_add(902); mrfifo_oldmode=newmode; } char cv_byte_p_num() { char i; for(i=0;(i<mrfifo_len&&i<6);i++) { if(!(MODE_BYTE&&mrfifo_p_onemode(mrfifo_data[i]))) { break; } } return i; } void cv_byte_emit(char len) { for(;len>1;len--) { int sok;/*FIXME just for debug, can be eliminated*/ sok=math_div_256(len); output_add(sok); // output_add(math_div_256(len)); mrfifo_shift(1); } mrfifo_shift(1); } char cv_byte_eat() { if(cv_byte_p_num()>=6) { output_add(924); } while(cv_byte_p_num()>=6) { cv_byte_emit(6); } output_add(901); cv_byte_emit(cv_byte_p_num()); return(0); } void cv_byte_start(unsigned char newmode) { /*FIXME*/ mrfifo_oldmode=newmode; } int math_div_256(char len) { /*FIXME optimize out i*/ unsigned int modulo; char i; modulo=*mrfifo_data; mrfifo_data[0]=0; for(i=2;i<len*2;i++) { modulo<<=4;/*shift mod*/ if(!(i%2)) { /*paros*/ modulo+=((mrfifo_data[i/2])&0xf0)>>4;/*shift data*/ /*div data -> data high*/ mrfifo_data[i/2]=((char)(((modulo/900)<<4)&0xf0)| ((mrfifo_data[i/2])&0x0f)); } else { /*paratlan*/ modulo+=(mrfifo_data[i/2])&0x0f;/*shift data*/ /*div data -> data high*/ mrfifo_data[i/2]=(((char)(modulo/900))&0x0f)| (0xf0&(mrfifo_data[i/2])); } modulo=modulo%900; /* mod mo*/ } return modulo; } void math_num_print(char len) { char i; signed char start=0; math_num_prepare(len); while(1) { *((int*)(mrfifo_data+start))=math_div_num(start,len); start+=2; len -=2; for(i=0;i<len;i++) { if(mrfifo_data[i+start]) { break; } } if(i>=len) { break; } } start-=2; for(;start>=0;start-=2) { output_add(*(int*)(mrfifo_data+start)); } } void math_num_prepare(char len) { char i; for(i=0;i<len;i++) { mrfifo_data[i]-='0'; } mrfifo_data[0]+=10; } int math_div_num(char start,char len) { unsigned int modulo; char i; modulo=(int)(mrfifo_data[start]); mrfifo_data[start]=0; for(i=1;i<len;i++) { modulo*=10; modulo+=mrfifo_data[i+start]; mrfifo_data[i+start]=((char)(modulo/900)); modulo=modulo%900; } return modulo; } char cv_bs_eat() { //putchar('y'); output_add(mrfifo_data[0]); return 1; } void cv_bs_start(unsigned char newmode) { //putchar('z'); output_add(913); return; } void output_add(int codeword) { //putchar('o'); if(2==mrfifo_round) { //putchar('O'); output_p_errcompute(codeword); output_p_print(codeword); } output_prlen++; } void err_init() { char i; for(i=0;i<ERRBUFLEN;i++) { errbuff[i]=0; } } unsigned int readerr(unsigned char k) { return (((k)%2)? ((*((unsigned int*)(errbuff+((k)*3/2))))&0x0fff) : ((*((unsigned int*)(errbuff+((k)*3/2))))>>4)); } void writerr(unsigned char k,unsigned int i) { unsigned char *n=errbuff+k*3/2; if((k)%2) { *(n+1)=i&0xff; *n=(i>>8)|((*n)&0xf0); } else { *n=i>>4; *(n+1)=((i&0xf)<<4)| ((*(n+1))&0x0f); } } unsigned long int onehalf_mul(unsigned int t1,unsigned char i) { unsigned long int t2; unsigned int t3; unsigned char aj[2]; *((int *)aj)=levelx[errlev][i]; /* (px+q)*(rx+t) = prx^2+(qr+tp)x+tq; and pr is char */ /* t1 = px +q , a[j] = rx +t * p=t1>>8, q=t1&0x0f * r=aj[0], t=aj[1] */ /*pr*/ //!!t2=p*r, ok t2=(t1>>8)*aj[0]; //!!t2=p*r*x t2<<=8; /*qr +tp*/ //!!t3=q*r t3=(t1&0x0ff)*aj[0]; //mydeb_puti(t3); //mydeb_puti(t2); /* * t2=t2+t3 * t2=p*r*x+q*r */ t2+=t3; // /* +tp*/ /* * t3=p*t */ t3=(t1>>8)*aj[1]; //mydeb_puti(t3); //mydeb_puti(t2); /* * t2=t2+t3 * t2=p*r*x+q*r+p*t */ t2+=t3; /* * t2=t2*x * t2=p*r*x^2+(q*r+p*t)*x */ t2<<=8; // /* tq */ /* * t3=q*t */ t3=(t1&0x0ff)*aj[1]; //mydeb_puti(t3); /* * t2=t2+t3 * t2=p*r*x^2+(q*r+p*t)*x+q*t */ t2+=t3; //mydeb_puti(t2); t2%=929; return t2; } #define KA (2<<(errlev)) void output_p_errcompute(int codeword) { unsigned int t1; unsigned char aj[2]; unsigned long int t2; unsigned char *t2c=((unsigned char *)&t2); unsigned int t3; signed char i; //FIXME if errlev<=5 t1=(codeword+readerr(KA-1))%929; //putchar('e'); //mydeb_puti(codeword); //mydeb_puti(t1); //mydeb_puti(readerr(KA-1)); //crlf(); for(i=KA-1;i>0;i--) { t2=onehalf_mul(t1,i); //mydeb_puti(t2); t3=929-t2; writerr(i,(readerr(i-1)+t3)%929); //putchar('E'); //mydeb_puti(t1); //mydeb_puti(t2); //mydeb_puti(t3); //mydeb_puti(levelx[errlev][i]); //mydebug(errbuff,24); } t2=onehalf_mul(t1,0); t3=929-t2; writerr(0,t3%929); //putchar('F'); //mydeb_puti(t2); //mydeb_puti(t3); //mydebug(errbuff,24); } void output_p_print(int codeword) { if(0==((output_prlen % cols))) { output_newline(); } print_codeword(codeword); } void error_print() { signed char i; for(i=KA-1;i>=0;i--) { putchar('e'); if(readerr(i)) { output_p_print(929-readerr(i)); } else { output_p_print(0); } } } void mrfifo_done() { /* pad chars */ while(output_prlen<(rows*cols-(2<<errlev))) { output_add(PADDING_WORD); } /* error chars */ error_print(); output_newline(); } void mrfifo_init() { unsigned char i; for(i=0;i<MRFIFO_DATA_LEN;i++) { mrfifo_data[i]=0; } mrfifo_len=0; mrfifo_oldmode=MODE_TEXT_ALPHA; mrfifo_datalen=0; cv_text_data=CV_NODATA; output_prlen=1; } void output_start() { line=0; bc_init_shifter(); print_codeword(STARTW); print_codeword(0); rows=((output_prlen+(2<<errlev)+cols/*would be (cols - 1) but + 1 for the length word */)/cols); if(rows<3) { rows=3; } output_add(rows*cols-(2<<errlev)); } void output_newline() { print_codeword(right_side()); print_stopword(); bc_print_graph(); crlf(); line++; if(line < rows) { bc_init_shifter(); print_codeword(STARTW); print_codeword(left_side()); } } //void output_end() //{ // output_prlen,cols,rows,line // // /*FIXME print the error code */ // //} /*-------------------------------------------------------*/ extern const unsigned char bc_itf_font[]; void mydebug(char*ptr,unsigned char len); extern const unsigned char bc_offsets[]; void bc_pdf417() { unsigned char ptrke; crlf(); crlf(); crlf(); //putchar('A'); err_init(); mydeb_puti(_asm("tsx\n pshh\n pula")); for(ptrke=1;ptrke<0x20;ptrke++) { *((&adex_value)+ptrke)=0xdd; }; print_stack(); line_spacing=0; bc.height/=8; mrfifo_init(); cols = getchar('b'); errlev = getchar('c'); datalenke=0; datalenke = getchar('d'); datalenke =datalenke << 8; datalenke += (signed int)((unsigned char)getchar('e')); if (datalenke == 0) { return ; } //0 length is not allowed if (errlev>4) { errlev=4 ; } //allowed errorlevel is 0...4 if (cols < 5) { cols=5 ; } //0 width is not allowed cols -= 4 ; if (cols > MAXCOL ) { cols=MAXCOL ; } print_mode.byte = 0; //any magnification off //proba(); mrfifo_round=1; mrfifo_datalen=datalenke; mrfifo_loop(); mrfifo_round=2; output_start(); mrfifo_init(); mrfifo_datalen=datalenke; mrfifo_loop(); mrfifo_done(); //proba(); bc.height*=8; print_stack(); } void print_codeword(codeword) { unsigned char n; unsigned int nn; putchar('P'); mydeb_puti(codeword); switch (line % 3) { case 0: codeword=codew0[codeword]; break; case 1: codeword=codew3[codeword]; break; case 2: codeword=codew6[codeword]; break; } nn = 0x8000 ; for ( n = 0 ; n < 16 ; n ++ ) { if (codeword&nn) bc_shift_bit_1(); else bc_shift_bit_0(); nn = nn >> 1; } bc_shift_bit_0(); } void print_stopword() { print_codeword(STOPW); bc_shift_bit_1(); } unsigned int left_side() { //putchar('L'); //mydeb_putc(line); //mydeb_putc(rows); //mydeb_putc(cols); //mydeb_putc(errlev); switch (line % 3) { case 0: return ((10*line) + rows/3); case 1: return ((10*line) + (errlev*3) + (rows%3)); case 2: return (60 + cols); } } unsigned int right_side() { switch (line % 3) { case 0: return ((10*line) + cols); case 1: return ((10*line) + (rows/3)); case 2: return (60 + (errlev*3) + (rows%3)); } } unsigned char proba() { line=0; //getchar('E'); bc_init_shifter(); //getchar('D'); print_codeword(STARTW); print_codeword(left_side()); print_codeword(453); print_codeword(841); print_codeword(63); print_codeword(753); print_codeword(897); print_codeword(88); print_codeword(right_side()); print_stopword(); //getchar('F'); bc_print_graph(); //getchar('G'); }

Retrieved from http://swpat.zpok.hu/pmwiki/pmwiki.php/Main/PDF417
Page last modified on July 14, 2005, at 08:37 PM