yylex() { register c; int i; if (pass == PASS_1) { /* scan the input file */ do c = nextchar(); while (isspace(c) && c != '\n'); if (ISALPHA(c)) c = inident(c); else if (isdigit(c)) c = innumber(c); else switch (c) { case '=': case '<': case '>': case '|': case '&': c = induo(c); break; case ASC_SQUO: case ASC_DQUO: c = instring(c); break; case ASC_COMM: do c = nextchar(); while (c != '\n' && c != '\0'); break; case CTRL('A'): c = CODE1; readcode(1); break; case CTRL('B'): c = CODE2; readcode(2); break; case CTRL('C'): c = CODE4; readcode(4); break; } /* produce the intermediate token file */ if (c <= 0) return(0); if (c <= 127) putc(c, tempfile); else putval(c); } else { /* read from intermediate token file */ c = getc(tempfile); if (c == EOF) return(0); if (c > 127) { c += 128; c = getval(c); } } return(c); }
/* uggghhhh, this is agonisingly painful. It turns out that * the original program bunched up codes into groups of 8, so we have * to waste on average about 5 or 6 bytes when we increase code size. * (and ghod, was this ever a complete bastard to track down.) * mmm, nice, tell me again why this format is dead? */ static void code_resync(int old, struct local_data *data) { int tmp; if (data->quirk & NOMARCH_QUIRK_NOSYNC) return; while(data->codeofs) if(!readcode(&tmp,old,data)) break; }
/* uggghhhh, this is agonisingly painful. It turns out that * the original program bunched up codes into groups of 8, so we have * to waste on average about 5 or 6 bytes when we increase code size. * (and ghod, was this ever a complete bastard to track down.) * mmm, nice, tell me again why this format is dead? */ void code_resync(int old) { int tmp; if (quirk & NOMARCH_QUIRK_NOSYNC) return; while(codeofs) if(!readcode(&tmp,old)) break; }
int main() { while (readheader()) { while (1) { int length = readcode(3); if (length == 0) break; int key = 0; while (1) { key = readcode(length); if (key == (1 << length) - 1) break; else printf("%c", header[length-1][key]); } } printf("\n"); } return 0; }
static unsigned char *_convert_lzw_dynamic(unsigned char *data_in, int max_bits,int use_rle, unsigned long in_len, unsigned long orig_len, int q, struct local_data *data) { unsigned char *data_out; int csize,orgcsize; int newcode,oldcode,k=0; int first=1,noadd; //printf("in_len = %d, orig_len = %d\n", in_len, orig_len); data->quirk = q; data->global_use_rle=use_rle; data->maxstr=(1<<max_bits); if((data_out=malloc(orig_len))==NULL) { //fprintf(stderr,"nomarch: out of memory!\n"); return NULL; } data->io.data_in_point=data_in; data->io.data_in_max=data_in+in_len; data->io.data_out_point=data_out; data->io.data_out_max=data_out+orig_len; data->dc_bitbox=data->dc_bitsleft=0; data->codeofs=0; outputrle(-1,NULL, &data->rd, &data->io); /* init RLE */ data->oldver=0; csize=9; /* initial code size */ if(max_bits==0) /* special case for static 12-bit */ data->oldver=1,csize=12,data->maxstr=4096; orgcsize=csize; inittable(orgcsize, data); oldcode=newcode=0; if(data->quirk & NOMARCH_QUIRK_SKIPMAX) data->io.data_in_point++; /* skip type 8 max. code size, always 12 */ if(max_bits==16) data->maxstr=(1<<*data->io.data_in_point++); /* but compress-type *may* change it (!) */ /* XXX */ if (data->maxstr > (1 << max_bits)) return NULL; data->nomarch_input_size = 0; while(1) { //printf("input_size = %d csize = %d\n", data->nomarch_input_size, csize); if(!readcode(&newcode,csize,data)) { //printf("readcode failed!\n"); break; } //printf("newcode = %x\n", newcode); if (data->quirk & NOMARCH_QUIRK_END101) { if (newcode == 0x101 /* data_out_point>=data_out_max */) { //printf("end\n"); break; } } noadd=0; if(first) { k=newcode,first=0; if(data->oldver) noadd=1; } if(newcode==256 && !data->oldver) { /* this *doesn't* reset the table (!), merely reduces code size again. * (It makes new strings by treading on the old entries.) * This took fscking forever to work out... :-( */ data->st_last=255; if (data->quirk & NOMARCH_QUIRK_START101) /* CM: Digital symphony data->quirk */ data->st_last++; /* XXX do we need a resync if there's a reset when *already* csize==9? * (er, assuming that can ever happen?) */ code_resync(csize, data); csize=orgcsize; if(!readcode(&newcode,csize,data)) break; } if((!data->oldver && newcode<=data->st_last) || (data->oldver && data->st_chr[newcode]!=UNUSED)) { outputstring(newcode, data); k=findfirstchr(newcode, data); } else { /* this is a bit of an assumption, but these ones don't seem to happen in * non-broken files, so... */ #if 0 /* actually, don't bother, just let the CRC tell the story. */ if(newcode>data->st_last+1) fprintf(stderr,"warning: bad LZW code\n"); #endif /* k=findfirstchr(oldcode);*/ /* don't think I actually need this */ outputstring(oldcode, data); outputchr(k, data); } if(data->st_last!=data->maxstr-1) { if(!noadd) { if(!addstring(oldcode,k,data)) { /* XXX I think this is meant to be non-fatal? * well, nothing for now, anyway... */ } if(data->st_last!=data->maxstr-1 && data->st_last==((1<<csize)-1)) { csize++; code_resync(csize-1, data); } } } oldcode=newcode; } if (~data->quirk & NOMARCH_QUIRK_NOCHK) { /* junk it on error */ if(data->io.data_in_point!=data->io.data_in_max) { free(data_out); return(NULL); } } return(data_out); }
int main(int argc, char **argv) { assert(argc >= 2); readcode(argv[1]); }