home *** CD-ROM | disk | FTP | other *** search
- /* hpcdtoppm (Hadmut's pcdtoppm) v0.6
- * Copyright (c) 1992, 1993, 1994 by Hadmut Danisch (danisch@ira.uka.de).
- * Permission to use and distribute this software and its
- * documentation for noncommercial use and without fee is hereby granted,
- * provided that the above copyright notice appear in all copies and that
- * both that copyright notice and this permission notice appear in
- * supporting documentation. It is not allowed to sell this software in
- * any way. This software is not public domain.
- */
-
-
- /* NOTE: don't use this file for compiling hpcdtoppm, it is heavily */
- /* modified by me (Günther Röhrich) */
-
- #include "hpcdtoppm.h"
-
-
-
- #define cro(p,d) {if(p) {p->im+=d*p->mwidth; p->iheight-=d;}}
- #define cru(p,d) {if(p) {p->iheight-=d;}}
- #define crl(p,d) {if(p) {p->im+=d; p->iwidth-=d;}}
- #define crr(p,d) {if(p) {p->iwidth-=d;}}
-
-
- void cropit(sizeinfo *si,implane *l,implane *c1,implane *c2)
- {dim x,y,s,w,h;
- sINT nl,nr,no,nu;
-
- uBYTE *ptr;
-
- melde("crop\n");
-
- if(si->imvlen || si->imhlen) error(E_INTERN);
- w=si->rdhlen;
- h=si->rdvlen;
-
- if((!l) || (l->iwidth != w) || (l->iheight != h)) error(E_INTERN);
-
- if(!monochrome)
- {if((!c1) || (c1->iwidth != w) || (c1->iheight != h)) error(E_INTERN);
- if((!c2) || (c2->iwidth != w) || (c2->iheight != h)) error(E_INTERN);
- }
-
-
- for(y=0,no=0;y<h;y++,no++)
- {for(x=0,ptr=(l->im)+y*(l->mwidth); x<w && (*ptr)<MAX_BLACK ;x++,ptr++);
- if(x<w) break;
- }
- cro(l ,no);
- cro(c1,no);
- cro(c2,no);
- h-=no;
-
-
- for(y=h-1,nu=0;y;y--,nu++)
- {for(x=0,ptr=(l->im)+y*(l->mwidth); x<w && (*ptr)<MAX_BLACK ;x++,ptr++);
- if(x<w) break;
- }
- cru(l ,nu);
- cru(c1,nu);
- cru(c2,nu);
- h-=nu;
-
-
- s=l->mwidth;
-
- for(x=0,nl=0;x<w;x++,nl++)
- {for(y=0,ptr=(l->im)+x; y<h && (*ptr)<MAX_BLACK ; y++, ptr+=s);
- if(y<h) break;
- }
- crl(l ,nl);
- crl(c1,nl);
- crl(c2,nl);
- w-=nl;
-
-
- for(x=w-1,nr=0;x;x--,nr++)
- {for(y=0,ptr=(l->im)+x; y<h && (*ptr)<MAX_BLACK ; y++, ptr+=s);
- if(y<h) break;
- }
- crr(l ,nr);
- crr(c1,nr);
- crr(c2,nr);
- w-=nr;
-
- if (do_melde)
- {
- if (no || nu || nr || nl )
- fprintf(stderr,"Cut off %d top, %d bottom, %d left, %d right, new size is %dx%d\n",
- no,nu,nl,nr,w,h);
- else
- fprintf(stderr,"Nothing cut off\n");
- }
-
- si->imvlen=h;
- si->imhlen=w;
- }
-
-
- void shrink(sizeinfo *si,implane *l,implane *c1,implane *c2)
- {dim w,h;
-
- melde("shrink\n");
-
- w=si->rdhlen;
- h=si->rdvlen;
-
- if((!l) || (l->iwidth != w) || (l->iheight != h)) error(E_INTERN);
-
- if(!monochrome)
- {if((!c1) || (c1->iwidth != w) || (c1->iheight != h)) error(E_INTERN);
- if((!c2) || (c2->iwidth != w) || (c2->iheight != h)) error(E_INTERN);
- }
-
- if((!si->imvlen) && (!si->imhlen)) /* no subrectangle given */
- {si->imvlen=si->rdvlen;
- si->imhlen=si->rdhlen;
- return;
- }
-
- if (si->imvlen>h || si->imvlen<1 ) error(E_INTERN);
- if (si->imvoff> si->rdvlen - si->imvlen) error(E_INTERN);
-
- if (si->imhlen>w || si->imhlen<1 ) error(E_INTERN);
- if (si->imhoff> si->rdhlen - si->imhlen) error(E_INTERN);
-
- cro(l ,si->imvoff);
- cro(c1,si->imvoff);
- cro(c2,si->imvoff);
-
- cru(l ,si->rdvlen - si->imvoff - si->imvlen);
- cru(c1,si->rdvlen - si->imvoff - si->imvlen);
- cru(c2,si->rdvlen - si->imvoff - si->imvlen);
-
- crl(l ,si->imhoff);
- crl(c1,si->imhoff);
- crl(c2,si->imhoff);
-
- crr(l ,si->rdhlen - si->imhoff - si->imhlen);
- crr(c1,si->rdhlen - si->imhoff - si->imhlen);
- crr(c2,si->rdhlen - si->imhoff - si->imhlen);
-
-
- }
-
-
-
- void halve(implane *p)
- {dim w,h,x,y;
- uBYTE *optr,*nptr;
-
- melde("halve\n");
- if ((!p) || (!p->im)) error(E_INTERN);
-
- w=p->iwidth/=2;
- h=p->iheight/=2;
-
-
- for(y=0;y<h;y++)
- {
- nptr=(p->im) + y*(p->mwidth);
- optr=(p->im) + 2*y*(p->mwidth);
-
- for(x=0;x<w;x++,nptr++,optr+=2)
- { *nptr = *optr;
- }
-
- }
-
- }
-
-
-
-
- void planealloc(implane *p, dim width, dim height)
- {
- melde("planealloc\n");
-
- p->iwidth=p->iheight=0;
- p->mwidth=width;
- p->mheight=height;
-
- p->mp = ( p->im = ( uBYTE * ) malloc (width*height*sizeof(uBYTE)) );
- if(!(p->im)) error(E_MEM);
- }
-
-
- enum ERRORS readplain(sizeinfo *si,int fak,implane *l,implane *c1,implane *c2)
- {dim i,w,h,hoff,hlen,voff,vlen;
- uBYTE *pl=0,*pc1=0,*pc2=0;
-
- melde("readplain\n");
-
- #ifdef DEBUG
- fprintf(stderr,"readplain %d %d %d %d %d %d %d\n",fak,si->w,si->h,si->rdhoff,si->rdhlen,si->rdvoff,si->rdvlen);
- #endif
-
- if(fak >= 0)
- {w =si->w *fak;
- h =si->h *fak;
- hoff=si->rdhoff*fak; if(hoff & 1 ) error(E_INTERN); /* Must be all even */
- hlen=si->rdhlen*fak; if(hlen & 1 ) error(E_INTERN);
- voff=si->rdvoff*fak; if(voff & 1 ) error(E_INTERN);
- vlen=si->rdvlen*fak; if(vlen & 1 ) error(E_INTERN);
- }
- else
- {fak = -fak;
- w =si->w /fak;
- h =si->h /fak;
- hoff=si->rdhoff/fak; if(hoff & 1 ) error(E_INTERN); /* Must be all even */
- hlen=si->rdhlen/fak; if(hlen & 1 ) error(E_INTERN);
- voff=si->rdvoff/fak; if(voff & 1 ) error(E_INTERN);
- vlen=si->rdvlen/fak; if(vlen & 1 ) error(E_INTERN);
- }
-
-
-
- if(l)
- { if ((l->mwidth<hlen) || (l->mheight<vlen) || (!l->im)) error(E_INTERN);
- l->iwidth=hlen;
- l->iheight=vlen;
- pl=l->im;
- }
-
- if(c1)
- { if ((c1->mwidth<(hlen>>1)) || (c1->mheight<(vlen>>1)) || (!c1->im)) error(E_INTERN);
- c1->iwidth=hlen>>1;
- c1->iheight=vlen>>1;
- pc1=c1->im;
- }
-
- if(c2)
- { if ((c2->mwidth<(hlen>>1)) || (c2->mheight<(vlen>>1)) || (!c2->im)) error(E_INTERN);
- c2->iwidth=hlen>>1;
- c2->iheight=vlen>>1;
- pc2=c2->im;
- }
-
- if(voff) SKIPr(w*3*(voff>>1));
-
- for(i=0;i<vlen>>1;i++)
- {
- if(pl)
- { if(hlen==w)
- {if(READ(pl,w)<1) return(E_READ);
- pl+= l->mwidth;
-
- if(READ(pl,w)<1) return(E_READ);
- pl+= l->mwidth;
- }
- else
- {SKIPr(hoff);
-
- if(READ(pl,hlen)<1) return(E_READ);
- pl+= l->mwidth;
-
- SKIPr(w-hlen); /* w - hlen - hoff + hoff */
-
- if(READ(pl,hlen)<1) return(E_READ);
- pl+= l->mwidth;
-
- SKIPr(w-hoff-hlen);
- }
- }
- else SKIPr(2*w);
-
- if(pc1)
- {
- if(hlen==w)
- {
- if(READ(pc1,w>>1)<1) return(E_READ);
- pc1+= c1->mwidth;
- }
- else
- {SKIPr((hoff)>>1);
- if(READ(pc1,hlen>>1)<1) return(E_READ);
- pc1+= c1->mwidth;
- SKIPr((w-hoff-hlen)>>1);
- }
- }
- else SKIPr(w>>1);
-
- if(pc2)
- {
- if(hlen==w)
- {
- if(READ(pc2,w>>1)<1) return(E_READ);
- pc2+= c2->mwidth;
- }
- else
- {SKIPr((hoff)>>1);
- if(READ(pc2,hlen>>1)<1) return(E_READ);
- pc2+= c2->mwidth;
- SKIPr((w-hoff-hlen)>>1);
- }
- }
- else SKIPr(w>>1);
-
-
- }
- RPRINT;
- return E_NONE;
- }
-
- void interpolate(implane *p)
- {dim w,h,x,y,yi;
- uBYTE *optr,*nptr,*uptr;
-
- melde("interpolate\n");
- if ((!p) || (!p->im)) error(E_INTERN);
-
- w=p->iwidth;
- h=p->iheight;
-
- if(p->mwidth < 2*w ) error(E_INTERN);
- if(p->mheight < 2*h ) error(E_INTERN);
-
-
- p->iwidth=2*w;
- p->iheight=2*h;
-
-
- for(y=0;y<h;y++)
- {yi=h-1-y;
- optr=p->im+ yi*p->mwidth + (w-1);
- nptr=p->im+2*yi*p->mwidth + (2*w - 2);
-
- nptr[0]=nptr[1]=optr[0];
-
- for(x=1;x<w;x++)
- { optr--; nptr-=2;
- nptr[0]=optr[0];
- nptr[1]=(((sINT)optr[0])+((sINT)optr[1])+1)>>1;
- }
- }
-
- for(y=0;y<h-1;y++)
- {optr=p->im + 2*y*p->mwidth;
- nptr=optr+p->mwidth;
- uptr=nptr+p->mwidth;
-
- for(x=0;x<w-1;x++)
- {
- nptr[0]=(((sINT)optr[0])+((sINT)uptr[0])+1)>>1;
- nptr[1]=(((sINT)optr[0])+((sINT)optr[2])+((sINT)uptr[0])+((sINT)uptr[2])+2)>>2;
- nptr+=2; optr+=2; uptr+=2;
- }
- *(nptr++)=(((sINT)*(optr++))+((sINT)*(uptr++))+1)>>1;
- *(nptr++)=(((sINT)*(optr++))+((sINT)*(uptr++))+1)>>1;
- }
-
-
- optr=p->im + (2*h-2)*p->mwidth;
- nptr=p->im + (2*h-1)*p->mwidth;
- for(x=0;x<w;x++)
- { *(nptr++) = *(optr++); *(nptr++) = *(optr++); }
-
- }
-
-
- void eerror(enum ERRORS e,char *file,int line)
- {
-
- switch(e)
- {case E_NONE: return;
- case E_IMP: fprintf(stderr,"Sorry, Not yet implemented. [%s:%d]\n",file,line); break;
- case E_READ: fprintf(stderr,"Error while reading.\n"); break;
- case E_WRITE: fprintf(stderr,"Error while writing.\n"); break;
- case E_INTERN: fprintf(stderr,"Internal error. [%s:%d]\n",file,line); break;
- case E_MEM: fprintf(stderr,"Not enough memory !\n"); break;
- case E_DISPLAY: fprintf(stderr, "Could not open display!\n"); break;
- case E_MAPFILE: fprintf(stderr, "Error while reading mapfile.\n"); break;
- case E_PICNUM: fprintf(stderr, "Wrong picture number.\n"); break;
- case E_ABORT: close_all();
- exit(0);
-
- case E_ARG: fprintf(stderr,"Usage: PhotoCDAGA PhotoCD-file [ppm-file] switches\n"
- "switches: -b name search for mapfile with basename\n"
- " -x overskip mode (tries to improve color quality)\n"
- " -s apply simple sharpness-operator on the Luma-channel\n"
- " -c try to cut off the black frame\n"
- " -n don't rotate\n"
- " -r rotate clockwise for portraits\n"
- " -l rotate counter-clockwise for portraits\n"
- " -h rotate twice, turn on head\n"
- " -m show decoding steps\n"
- " -c- correct darker\n"
- " -c+ correct brighter\n"
- " -pgm create grayscale pgm output\n"
- " -ppm create ppm output\n"
- " -gray use grayscale display\n"
- " -vga use VGA screenmode\n"
- " -orig use original system drawing functions\n"
- " -0 n show overview starting with picture n\n"
- " -1 extract 128x192 (Base/16)\n"
- " -2 extract 256x384 (Base/4)\n"
- " -3 extract 512x768 (Base), default\n"); break;
- }
- close_all();
- exit(10);
- }
-
-
-
-
- static void flip_corr(dim w,dim h,uBYTE **ptr,sdim *ystep,sdim *xstep)
- {
- if(flvert)
- {
- (*ptr) += (h-1)* (*ystep);
- (*ystep) = -(*ystep);
- }
-
- if(flhori)
- {
- (*ptr) += (w-1)* (*xstep);
- (*xstep) = -(*xstep);
- }
- }
-
-
-
-
- static void call_1plane(OUT1PL proc, FILE *fout,
- dim w, dim h,uBYTE * ptr,
- sdim zeil, sdim pix)
- {
- flip_corr(w,h,&ptr,&zeil,&pix);
- (*proc)(fout,w,h,ptr,zeil,pix);
- }
-
-
-
- static void do_1plane(OUT1PL proc, FILE *fout,
- dim w,dim h,implane *g,enum TURNS t)
- {
- switch(t)
- {case T_NONE: call_1plane(proc,fout,w,h,g->im,g->mwidth,1);
- break;
- case T_RIGHT:call_1plane(proc,fout,h,w,g->im + g->mwidth * ( g->iheight - 1) , 1 , -(g->mwidth));
- break;
- case T_LEFT: call_1plane(proc,fout,h,w,g->im + g->iwidth - 1 , -1 , (g->mwidth));
- break;
- case T_HEAD: call_1plane(proc,fout,w,h,g->im + g->iwidth - 1 + g->mwidth * ( g->iheight - 1) , -(g->mwidth) , -1);
- break;
- default:error(E_INTERN);
- }
-
- }
-
-
-
-
-
-
-
- static void call_3plane(OUT3PL proc, FILE *fout, dim w,dim h,
- uBYTE *rptr,sdim rzeil,sdim rpix,
- uBYTE *gptr,sdim gzeil,sdim gpix,
- uBYTE *bptr,sdim bzeil,sdim bpix)
- {
- flip_corr(w,h,&rptr,&rzeil,&rpix);
- flip_corr(w,h,&gptr,&gzeil,&gpix);
- flip_corr(w,h,&bptr,&bzeil,&bpix);
-
- (*proc)(fout,w,h,rptr,rzeil,rpix,gptr,gzeil,gpix,bptr,bzeil,bpix );
- }
-
-
- static void do_3plane(OUT3PL proc,FILE *fout,dim w,dim h,
- implane *r,implane *g,implane *b,
- enum TURNS t)
- {
- switch(t)
- {case T_NONE: call_3plane(proc,fout,w,h,r->im,r->mwidth,1,
- g->im,g->mwidth,1,
- b->im,b->mwidth,1);
- break;
- case T_RIGHT:call_3plane(proc,fout,h,w,r->im + r->mwidth * ( r->iheight - 1) , 1 , -(r->mwidth),
- g->im + g->mwidth * ( g->iheight - 1) , 1 , -(g->mwidth),
- b->im + b->mwidth * ( b->iheight - 1) , 1 , -(b->mwidth));
- break;
- case T_LEFT: call_3plane(proc,fout,h,w,r->im + r->iwidth - 1 , -1 , (r->mwidth),
- g->im + g->iwidth - 1 , -1 , (g->mwidth),
- b->im + b->iwidth - 1 , -1 , (b->mwidth));
- break;
- case T_HEAD: call_3plane(proc,fout,w,h,r->im + r->iwidth - 1 + r->mwidth * ( r->iheight - 1) , -(r->mwidth) , -1,
- g->im + g->iwidth - 1 + g->mwidth * ( g->iheight - 1) , -(g->mwidth) , -1,
- b->im + b->iwidth - 1 + b->mwidth * ( b->iheight - 1) , -(b->mwidth) , -1);
- break;
- default:error(E_INTERN);
- }
-
- }
-
-
-
- static sINT testbegin(void)
- {sINT i,j;
- for(i=j=0;i<32;i++)
- if(sbuffer[i]==0xff) j++;
-
- return (j>30);
-
- }
-
-
- sINT Skip4Base(void)
- {sINT cd_offset,cd_offhelp;
-
- cd_offset = L_Head + L_Base16 + L_Base4 + L_Base ;
- SEEK(cd_offset+3);
- EREADBUF;
- cd_offhelp=((((sINT)sbuffer[510])<<8)|sbuffer[511]) + 1;
-
- cd_offset+=cd_offhelp;
-
- SEEK(cd_offset);
- EREADBUF;
- while(!testbegin())
- {cd_offset++;
- EREADBUF;
- }
- return cd_offset;
- }
-
-
-
- void writepicture(FILE *fout, sizeinfo *si,
- implane *r,implane *g,implane *b,
- enum TURNS t)
- {dim w,h;
-
- w=si->imhlen;
- h=si->imvlen;
-
- melde("writepicture\n");
- if((!r) || (r->iwidth != w ) || (r->iheight != h) || (!r->im)) error(E_INTERN);
-
- if(!monochrome)
- {
- if((!g) || (g->iwidth != w ) || (g->iheight != h) || (!g->im)) error(E_INTERN);
- if((!b) || (b->iwidth != w ) || (b->iheight != h) || (!b->im)) error(E_INTERN);
- }
-
- switch(outfor)
- {
- case O_PPM: do_3plane(write_ppm ,fout,w,h,r,g,b,t); break;
- case O_DCOLOR: do_3plane(write_dcolor ,fout,w,h,r,g,b,t); break;
- case O_DOVER_COLOR: do_3plane(write_dover_color ,fout,w,h,r,g,b,t); break;
-
- case O_PGM: do_1plane(write_pgm ,fout,w,h,r,t); break;
- case O_DGRAY: do_1plane(write_dgray ,fout,w,h,r,t); break;
- case O_DOVER_GRAY: do_1plane(write_dover_gray ,fout,w,h,r,t); break;
-
- default: error(E_INTERN);
- }
-
-
- }
-
-
-
- struct ph1
- {char id1[8];
- uBYTE ww1[14];
- char id2[20];
- char id3[4*16+4];
- short ww2;
- char id4[20];
- uBYTE ww3[2*16+1];
- char id5[4*16];
- uBYTE idx[11*16];
- } ;
-
-
- void druckeid(void)
- {struct ph1 *d;
- char ss[100];
-
- d=(struct ph1 *)sbuffer;
-
- #define dr(feld,kennung) \
- strncpy(ss,feld,sizeof(feld));\
- ss[sizeof(feld)]=0;\
- fprintf(stderr,"%s: %s \n",kennung,ss);
-
-
- dr(d->id1,"Id1")
- dr(d->id2,"Id2")
- dr(d->id3,"Id3")
- dr(d->id4,"Id4")
- dr(d->id5,"Id5")
-
- #undef dr
-
- }
-
- struct pcdquad { uBYTE len,highseq,lowseq,key;};
- struct pcdhqt { uBYTE entries; struct pcdquad entry[256];};
- struct myhqt { uINT seq,mask,len; uBYTE key; };
-
- static struct myhqt myhuff0[256],myhuff1[256],myhuff2[256];
- static sINT myhufflen0=0,myhufflen1=0,myhufflen2=0;
-
-
-
- static void readhqtsub(struct pcdhqt *quelle,struct myhqt *ziel,sINT *anzahl)
- #define E ((uINT) 1)
- {sINT i;
- struct pcdquad *sub;
- struct myhqt *help;
- *anzahl=(quelle->entries)+1;
-
- for(i=0;i<*anzahl;i++)
- {sub = (struct pcdquad *)(((uBYTE *)quelle)+1+i*sizeof(*sub));
- help=ziel+i;
-
- help->seq = (((uINT) sub->highseq) << 24) |(((uINT) sub->lowseq) << 16);
- help->len = ((uINT) sub->len) +1;
- help->key = sub->key;
-
- #ifdef DEBUGhuff
- fprintf(stderr," Anz: %d A1: %08x A2: %08x X:%02x %02x %02x %02x Seq: %08x Laenge: %d %d\n",
- *anzahl,(uINT)sbuffer,(uINT)sub,
- ((uBYTE *)sub)[0],((uBYTE *)sub)[1],((uBYTE *)sub)[2],((uBYTE *)sub)[3],
- help->seq,help->len,sizeof(uBYTE));
- #endif
-
- if(help->len > 16) error(E_HUFF);
-
- help->mask = ~ ( (E << (32-help->len)) -1);
-
- }
- #ifdef DEBUG
- for(i=0;i<*anzahl;i++)
- {help=ziel+i;
- fprintf(stderr,"H: %3d %08lx & %08lx (%2d) = %02x = %5d %8x\n",
- i, help->seq,help->mask,help->len,help->key,(sBYTE)help->key,
- help->seq & (~help->mask));
- }
- #endif
-
- #undef E
- }
-
-
-
-
- void readhqt(sINT n)
- {
- uBYTE *ptr;
-
- melde("readhqt\n");
- EREADBUF;
- ptr = sbuffer;
-
- readhqtsub((struct pcdhqt *)ptr,myhuff0,&myhufflen0);
-
- if(n<2) return;
- ptr+= 1 + 4* myhufflen0;
- readhqtsub((struct pcdhqt *)ptr,myhuff1,&myhufflen1);
-
- if(n<3) return;
- ptr+= 1 + 4* myhufflen1;
- readhqtsub((struct pcdhqt *)ptr,myhuff2,&myhufflen2);
-
- }
-
-
-
- #ifdef FASTHUFF
-
- static struct myhqt *HTAB0[0x10000],*HTAB1[0x10000],*HTAB2[0x10000];
-
- static void inithuff(sINT hlen,struct myhqt *ptr,struct myhqt *TAB[])
- {sINT i,n;
- sINT seq,len;
- struct myhqt *help;
-
- for(i=0;i<0x10000;i++) TAB[i]=0;
-
- for(n=0;n<hlen;n++)
- {help=ptr+n;
- seq=(help->seq)>>16;
- len=help->len;
-
- for(i=0;i<(1<<(16-len));i++)
- TAB[seq | i] = help;
- }
- }
- #endif
-
-
-
- static char *pn[]={"Luma Channel","Chroma1 Channel","Chroma2 Channel"};
-
-
- void decode(sizeinfo *si,int fak,implane *f,implane *f1,implane *f2,sINT autosync)
- {dim w,h,hoff,hlen,hende,voff,vlen,vende,anfang,ende;
- sINT htlen,sum,do_inform,part;
- uINT sreg,maxwidth;
- uINT inh,n,zeile,segment,ident;
- struct myhqt *hp;
-
- uBYTE *nptr;
- uBYTE *lptr;
-
- #define nextbuf { nptr=sbuffer; if(READBUF<1) { if(!do_rep) error(E_READ); \
- fprintf(stderr,"Read error\n"); \
- return; } }
- #define checkbuf { if (nptr >= sbuffer + sizeof(sbuffer)) nextbuf; }
-
- #ifdef U_TOO_LONG
- #define shiftreg(n) sreg = (sreg<< n ) & 0xffffffff;
- #else
- #define shiftreg(n) sreg<<=n;
- #endif
-
- #define shiftout(n){ shiftreg(n); inh-=n; \
- while (inh<=24) \
- {checkbuf; \
- sreg |= ((uINT)(*(nptr++)))<<(24-inh);\
- inh+=8;\
- }\
- }
- #define issync ((sreg & 0xffffff00) == 0xfffffe00)
- #define brutesync ((sreg & 0x00fff000) == 0x00fff000)
- #define seeksync { while (!brutesync) shiftout(8); while (!issync) shiftout(1);}
-
- #ifdef FASTHUFF
- struct myhqt **HTAB;
- HTAB=0;
- inithuff(myhufflen0,myhuff0,HTAB0);
- inithuff(myhufflen1,myhuff1,HTAB1);
- inithuff(myhufflen2,myhuff2,HTAB2);
- #define SETHUFF0 HTAB=HTAB0;
- #define SETHUFF1 HTAB=HTAB1;
- #define SETHUFF2 HTAB=HTAB2;
- #define FINDHUFF(x) {x=HTAB[sreg>>16];}
-
- #else
-
- sINT i;
- struct myhqt *htptr;
- htptr=0;
- #define SETHUFF0 { htlen=myhufflen0 ; htptr = myhuff0 ; }
- #define SETHUFF1 { htlen=myhufflen1 ; htptr = myhuff1 ; }
- #define SETHUFF2 { htlen=myhufflen2 ; htptr = myhuff2 ; }
- #define FINDHUFF(x) {for(i=0, x=htptr;(i<htlen) && ((sreg & x ->mask)!= x->seq); i++,x++); \
- if(i>=htlen) x=0;}
- #endif
-
- melde("decode\n");
- anfang=ende=0;
-
- if(fak >= 0)
- {w =si->w *fak;
- h =si->h *fak;
- hoff=si->rdhoff*fak; if(hoff & 1 ) error(E_INTERN); /* Must be all even */
- hlen=si->rdhlen*fak; if(hlen & 1 ) error(E_INTERN); hende=hlen+hoff;
- voff=si->rdvoff*fak; if(voff & 1 ) error(E_INTERN);
- vlen=si->rdvlen*fak; if(vlen & 1 ) error(E_INTERN); vende=vlen+voff;
- }
- else
- {fak = -fak;
- w =si->w /fak;
- h =si->h /fak;
- hoff=si->rdhoff/fak; if(hoff & 1 ) error(E_INTERN); /* Must be all even */
- hlen=si->rdhlen/fak; if(hlen & 1 ) error(E_INTERN); hende=hlen+hoff;
- voff=si->rdvoff/fak; if(voff & 1 ) error(E_INTERN);
- vlen=si->rdvlen/fak; if(vlen & 1 ) error(E_INTERN); vende=vlen+voff;
- }
-
-
- if( f && ((! f->im) || ( f->iheight != vlen ) || (f->iwidth != hlen ))) error(E_INTERN);
- if( f1 && ((!f1->im) || (f1->iheight != vlen/2) || (f1->iwidth != hlen/2))) error(E_INTERN);
- if( f2 && ((!f2->im) || (f2->iheight != vlen/2) || (f2->iwidth != hlen/2))) error(E_INTERN);
-
- htlen=sreg=maxwidth=0;
- zeile=0;
- nextbuf;
- inh=32;
- lptr=0;
- part=do_inform=0;
- shiftout(16);
- shiftout(16);
-
- if(autosync) seeksync;
-
- if(!issync)
- { if(!do_rep) error(E_SEQ6);
- else
- {fprintf(stderr,"Image does not start with synchron mark, seeking...\n");
- seeksync;
- do_inform=1;
- }
- }
-
- n=0;
-
- for(;;)
- {
- if (issync)
- {shiftout(24);
- ident=sreg>>16;
- shiftout(16);
-
- zeile=(ident>>1) & 0x1fff;
- segment=ident>>14;
- if(do_inform) {fprintf(stderr,"Synchron mark found Line %d\n",zeile);do_inform=0;}
- #ifdef DEBUG
- fprintf(stderr,"Id %4x Zeile: %6d Seg %3d Pix bisher: %5d Position: %8lx+%5lx=%8x\n",
- ident,zeile,segment,n,bufpos,nptr-sbuffer,bufpos+nptr-sbuffer);
- #endif
-
-
- if(lptr && (n!=maxwidth))
- {if(!do_rep)error(E_SEQ1);
- else fprintf(stderr,"Line %d in %s : wrong length of last line (%d)\n",zeile,pn[part],n);
- }
- n=0;
-
- if(zeile==h) {RPRINT; return; }
- if(zeile >h)
- { if(!do_rep) error(E_SEQ2);
- else
- {fprintf(stderr,"Wrong line number %d, ignoring line\n",zeile);
- seeksync;
- n=maxwidth;
- do_inform=1;
- }
- }
- else switch(segment)
- {
- case 1: if(!do_rep) error(E_SEQ3);
- fprintf(stderr,"Abnormal line tag in %d, interpreting as Luma tag\n",zeile);
- case 0: maxwidth=w;
- if((!f) && autosync) {seeksync; n=maxwidth; break;}
- if(!f) error(E_SEQ7);
- if((zeile<voff) || (zeile >= vende)) {seeksync; n=maxwidth; break;}
- anfang=hoff; ende=hende;
- lptr=f->im + (zeile-voff)*f->mwidth;
- SETHUFF0;
- part=0;
- break;
-
- case 2: maxwidth=w>>1;
- if(!f1) return;
- /*if((!f1) && autosync) {seeksync; break;}*/
- if((zeile<voff) || (zeile >= vende)) {seeksync; n=maxwidth; break;}
- anfang=hoff>>1; ende=hende>>1;
- lptr=f1->im + ((zeile-voff)>>1)*f1->mwidth;
- SETHUFF1;
- part=1;
- break;
-
- case 3: maxwidth=w>>1;
- if(!f2) return;
- /*if((!f2) && autosync) {seeksync; break;}*/
- if((zeile<voff) || (zeile >= vende)) {seeksync; n=maxwidth; break;}
- anfang=hoff>>1; ende=hende>>1;
- lptr=f2->im + ((zeile-voff)>>1)*f2->mwidth;
- SETHUFF2;
- part=2;
- break;
-
- default:error(E_SEQ3);
- }
- }
- else
- {
- if(!lptr) error(E_SEQ6);
-
- if(n>maxwidth)
- {
- #ifdef DEBUG
- fprintf(stderr,"Register: %08lx Pos: %08lx\n",sreg,bufpos+nptr-sbuffer);
- #endif
- if (!do_rep) error(E_SEQ4);
- else { fprintf(stderr,"Missing synchron mark in %s line %d\n",pn[part],zeile);
- seeksync;
- do_inform=1;
- n=maxwidth;
- }
- }
- else
- {FINDHUFF(hp);
- if(!hp)
- { if(!do_rep) error(E_SEQ5);
- fprintf(stderr,"Unable to decode, ignoring rest of line\n");
- seeksync;
- n=maxwidth;
- do_inform=1;
- }
- else
- {if((n>= anfang) && (n<ende))
- {sum=((sINT)(*lptr)) + ((sBYTE)hp->key);
- NORM(sum);
- *(lptr++) = sum;
- }
-
- n++;
- shiftout(hp->len);
- }
- }
- }
-
- }
-
-
- #undef nextbuf
- #undef checkbuf
- #undef shiftout
- #undef issync
- #undef seeksync
-
- }