This is format.c in view mode; [Download] [Up]
/* hpcdtoppm (Hadmut's pcdtoppm) v0.5 * 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 { 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,(signed char)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 } 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; }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.