Hide minor edits - Show changes to markup
[=
=]
extern unsigned char adex_value;
//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*/
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() mydeb_puti(_asm("tsx\n pshh\n pula"));
void mydebug(char*ptr,unsigned char len)
{
for(;len>0;len--) { mydeb_putc(*ptr); ptr++; } crlf();
}
/*-------------------------------------------------------*/
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();
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 */
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);
/*-------------------------------------------------------*/
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);
}
unsigned char mrfifo_newmode()
{
unsigned char i;
unsigned char thismode;
thismode=mrfifo_p_onemode(mrfifo_data[0]);
if(thismode&MODE_NUMERIC) { return MODE_NUMERIC; }
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;
}
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');
}