home *** CD-ROM | disk | FTP | other *** search
- /* hpcdtoppm (Hadmut's pcdtoppm) v0.4
- * Copyright (c) 1992, 1993 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.
- */
-
- #include "hpcdtoppm.h"
-
- struct pcdquad { uBYTE len,highseq,lowseq,key;};
- struct pcdhqt { uBYTE entries; struct pcdquad entry[256];};
- struct myhqt { unsigned long seq,mask,len; uBYTE key; };
-
-
- #define E ((unsigned long) 1)
-
-
- static void readhqtsub(quelle,ziel,anzahl)
- struct pcdhqt *quelle;
- struct myhqt *ziel;
- int *anzahl;
- {int 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 = (((unsigned long) sub->highseq) << 24) |(((unsigned long) sub->lowseq) << 16);
- help->len = ((unsigned long) 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,sbuffer,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,(signed char)help->key,
- help->seq & (~help->mask));
- }
- #endif
-
- }
-
- #undef E
-
-
-
-
-
- static struct myhqt myhuff0[256],myhuff1[256],myhuff2[256];
- static int myhufflen0=0,myhufflen1=0,myhufflen2=0;
-
- void readhqt(w,h,n)
- dim w,h;
- int 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(hlen,ptr,TAB)
- int hlen;
- struct myhqt *ptr,*TAB[];
- {int i,n;
- long 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(w,h,f,f1,f2,autosync)
- dim w,h;
- implane *f,*f1,*f2;
- int autosync;
- {int htlen,sum,do_inform,part;
- unsigned long sreg,maxwidth;
- unsigned int inh,n,zeile,segment,ident;
- struct myhqt *hp;
-
- uBYTE *nptr;
- uBYTE *lptr;
-
- #define nextbuf { nptr=sbuffer; EREADBUF; }
- #define checkbuf { if (nptr >= sbuffer + sizeof(sbuffer)) nextbuf; }
- #define shiftout(n){ sreg<<=n; inh-=n; \
- while (inh<=24) \
- {checkbuf; \
- sreg |= ((unsigned long)(*(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
-
- int 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");
-
- if( f && ((! f->im) || ( f->iheight < h ) || (f->iwidth<w ))) error(E_INTERN);
- if( f1 && ((!f1->im) || (f1->iheight < h/2) || (f1->iwidth<w/2))) error(E_INTERN);
- if( f2 && ((!f2->im) || (f2->iheight < h/2) || (f2->iwidth<w/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;
-
- 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 %u\n",zeile);do_inform=0;}
- #ifdef DEBUG
- fprintf(stderr,"Id %4x Zeile: %6u 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 %u in %s : wrong length of last line (%u)\n",zeile,pn[part],n);
- }
- n=0;
-
- if(zeile==h) {RPRINT; return; }
- if(zeile >h) error(E_SEQ2);
-
- switch(segment)
- {
- case 0: if((!f) && autosync) {seeksync; break;}
- if(!f) error(E_SEQ7);
- lptr=f->im + zeile*f->mwidth;
- maxwidth=f->iwidth;
- SETHUFF0;
- part=0;
- break;
-
- case 2: if((!f1) && autosync) {seeksync; break;}
- if(!f1) return;
- if(!f1) error(E_SEQ7);
- lptr=f1->im + (zeile>>1)*f1->mwidth;
- maxwidth=f1->iwidth;
- SETHUFF1;
- part=1;
- break;
-
- case 3: if((!f2) && autosync) {seeksync; break;}
- if(!f2) return;
- if(!f2) error(E_SEQ7);
- lptr=f2->im + (zeile>>1)*f2->mwidth;
- maxwidth=f2->iwidth;
- 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 %u\n",pn[part],zeile);
- seeksync;
- do_inform=1;
- n=maxwidth;
- }
- }
- else
- {FINDHUFF(hp);
- if(!hp) error(E_SEQ5);
-
- sum=((int)(*lptr)) + ((sBYTE)hp->key);
- NORM(sum);
- *(lptr++) = sum;
-
- n++;
- shiftout(hp->len);
- }
- }
-
- }
-
-
- #undef nextbuf
- #undef checkbuf
- #undef shiftout
- #undef issync
- #undef seeksync
-
- }
-
-
-
-
-
-
-
-
- enum ERRORS readplain(fpcd,w,h,l,c1,c2)
- FILE *fpcd;
- dim w,h;
- implane *l,*c1,*c2;
- {dim i;
- uBYTE *pl=0,*pc1=0,*pc2=0;
- melde("readplain\n");
-
- if(l)
- { if ((l->mwidth<w) || (l->mheight<h) || (!l->im)) error(E_INTERN);
- l->iwidth=w;
- l->iheight=h;
- pl=l->im;
- }
-
- if(c1)
- { if ((c1->mwidth<w/2) || (c1->mheight<h/2) || (!c1->im)) error(E_INTERN);
- c1->iwidth=w/2;
- c1->iheight=h/2;
- pc1=c1->im;
- }
-
- if(c2)
- { if ((c2->mwidth<w/2) || (c2->mheight<h/2) || (!c2->im)) error(E_INTERN);
- c2->iwidth=w/2;
- c2->iheight=h/2;
- pc2=c2->im;
- }
-
- for(i=0;i<h/2;i++)
- {
- if(pl)
- {
- if(fread(pl,w,1,fpcd)<1) return(E_READ);
- pl+= l->mwidth;
-
- if(fread(pl,w,1,fpcd)<1) return(E_READ);
- pl+= l->mwidth;
- }
- else SKIPr(2*w);
-
- if(pc1)
- { if(fread(pc1,w/2,1,fpcd)<1) return(E_READ);
- pc1+= c1->mwidth;
- }
- else SKIPr(w/2);
-
- if(pc2)
- { if(fread(pc2,w/2,1,fpcd)<1) return(E_READ);
- pc2+= c2->mwidth;
- }
- else SKIPr(w/2);
-
-
- }
- RPRINT;
- return E_NONE;
- }
-