This is pcd.c in view mode; [Download] [Up]
/* hpcdtoppm (Hadmut's pcdtoppm) v0.2 * Copyright (c) 1992 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. */ /* define DEBUG for some debugging informations, just remove the x from xDEBUG */ #define xDEBUG /* define MELDUNG if you want to see what is happening and what takes time, just remove the x from xMeldung */ #define xMELDUNG /* define OWN_WRITE either here or by compiler-option if you don't want to use the pbmplus-routines for writing */ #define OWN_WRITE /* If the own routines are used, this is the size of the buffer in bytes. You can shrink if needed. */ #define own_BUsize 50000 #include <stdlib.h> // on NeXT, at least #include <string.h> // on NeXT, at least #include <stdio.h> #ifndef OWN_WRITE #include "ppm.h" #else /* The header for the ppm-files */ #define PPM_Header "P6\n%d %d\n255\n" #endif typedef unsigned char uBYTE; typedef unsigned long dim; #define BaseW ((dim)768) #define BaseH ((dim)512) #define SECSIZE 0x800 #define SeHead 2 #define L_Head (1+SeHead) #define SeBase16 18 #define L_Base16 (1+SeBase16) #define SeBase4 72 #define L_Base4 (1+SeBase4) #define SeBase 288 #define L_Base (1+SeBase) enum ERRORS { E_NONE,E_READ,E_WRITE,E_INTERN,E_ARG,E_OPT,E_MEM,E_HUFF, E_SEQ,E_SEQ1,E_SEQ2,E_SEQ3,E_SEQ4,E_SEQ5,E_SEQ6,E_SEQ7,E_POS,E_IMP }; enum TURNS { T_NONE,T_RIGHT,T_LEFT }; enum SIZES { S_UNSPEC,S_Base16,S_Base4,S_Base,S_4Base,S_16Base,S_Over }; /* Default taken when no size parameter given */ #define S_DEFAULT S_Base16 struct _implane {dim mwidth,mheight, iwidth,iheight; uBYTE *im; }; typedef struct _implane implane; enum ERRORS readplain(); void interpolate(); // static void writepicture(); void readhqt(); void decode(); static FILE *fin=0,*fout=0; static char *ppmname=0; static uBYTE sbuffer[SECSIZE]; /* Using preprocessor for inline-procs */ #ifdef DEBUG #define SEEK(x) { if (fseek(fin,((x) * SECSIZE),0)) error(E_READ);\ fprintf(stderr,"S-Position %x\n",ftell(fin)); } #else #define SEEK(x) { if (fseek(fin,((x) * SECSIZE),0)) error(E_READ);} #endif #define SKIP(n) { if (fseek(fin,(n),1)) error(E_READ);} #define SKIPr(n) { if (fseek(fin,(n),1)) return(E_READ);} #define READBUF fread(sbuffer,sizeof(sbuffer),1,fin) #define READBUF_NeXT fread(sbuffer,sizeof(sbuffer),1,NeXT_fin) #define xTRIF(x,u,o,a,b,c) ((x)<(u)? (a) : ( (x)>(o)?(c):(b) )) #define xNORM(x) x=TRIF(x,0,255,0,x,255) #define NORM(x) { if(x<0) x=0; else if (x>255) x=255;} #ifdef MELDUNG #define melde(x) fprintf(stderr,x) #else #define melde(x) #endif void error(e) enum ERRORS e; { switch(e) {case E_NONE: return; case E_IMP: fprintf(stderr,"Sorry, Not yet implemented.\n"); 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.\n"); break; case E_ARG: fprintf(stderr,"Arguments !\n"); fprintf(stderr,"Usage: hpcdtoppm [options] pcd-file [ppm-file]\n"); fprintf(stderr,"Opts:\n"); fprintf(stderr," -i Give some (buggy) informations from fileheader\n"); fprintf(stderr," -s Apply simple sharpness-operator on the Luma-channel\n"); fprintf(stderr," -d Show differential picture only \n"); fprintf(stderr," -r Rotate clockwise for portraits\n"); fprintf(stderr," -l Rotate counter-clockwise for portraits\n"); fprintf(stderr," -0 Extract thumbnails from Overview file\n"); fprintf(stderr," -1 Extract 128x192 from Image file\n"); fprintf(stderr," -2 Extract 256x384 from Image file\n"); fprintf(stderr," -3 Extract 512x768 from Image file\n"); fprintf(stderr," -4 Extract 1024x1536 from Image file\n"); fprintf(stderr," -5 Extract 2048x3072 from Image file\n"); break; case E_OPT: fprintf(stderr,"These Options are not allowed together.\n");break; case E_MEM: fprintf(stderr,"Not enough memory !\n"); break; case E_HUFF: fprintf(stderr,"Error in Huffman-Code-Table\n"); break; case E_SEQ: fprintf(stderr,"Error in Huffman-Sequence\n"); break; case E_SEQ1: fprintf(stderr,"Error1 in Huffman-Sequence\n"); break; case E_SEQ2: fprintf(stderr,"Error2 in Huffman-Sequence\n"); break; case E_SEQ3: fprintf(stderr,"Error3 in Huffman-Sequence\n"); break; case E_SEQ4: fprintf(stderr,"Error4 in Huffman-Sequence\n"); break; case E_SEQ5: fprintf(stderr,"Error5 in Huffman-Sequence\n"); break; case E_SEQ6: fprintf(stderr,"Error6 in Huffman-Sequence\n"); break; case E_SEQ7: fprintf(stderr,"Error7 in Huffman-Sequence\n"); break; case E_POS: fprintf(stderr,"Error in file-position\n"); break; default: fprintf(stderr,"Unknown error %d ???\n",e);break; } if(fin) fclose(fin); if(fout && ppmname) fclose(fout); exit(9); } void planealloc(p,width,height) implane *p; dim width,height; { p->iwidth=p->iheight=0; p->mwidth=width; p->mheight=height; p->im = ( uBYTE * ) malloc (width*height*sizeof(uBYTE)); if(!(p->im)) error(E_MEM); } enum ERRORS readplain(w,h,l,c1,c2,fin) FILE *fin; 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,fin)<1) return(E_READ); pl+= l->mwidth; if(fread(pl,w,1,fin)<1) return(E_READ); pl+= l->mwidth; } else SKIPr(2*w); if(pc1) { if(fread(pc1,w/2,1,fin)<1) return(E_READ); pc1+= c1->mwidth; } else SKIPr(w/2); if(pc2) { if(fread(pc2,w/2,1,fin)<1) return(E_READ); pc2+= c2->mwidth; } else SKIPr(w/2); } #ifdef DEBUG_EXTRA fprintf(stderr,"R-Position %x\n",ftell(fin)); #endif return E_NONE; } void interpolate(p) 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]=(((int)optr[0])+((int)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]=(((int)optr[0])+((int)uptr[0])+1)>>1; nptr[1]=(((int)optr[0])+((int)optr[2])+((int)uptr[0])+((int)uptr[2])+2)>>2; nptr+=2; optr+=2; uptr+=2; } *(nptr++)=(((int)*(optr++))+((int)*(uptr++))+1)>>1; *(nptr++)=(((int)*(optr++))+((int)*(uptr++))+1)>>1; } bcopy(p->im + (2*h-2)*p->mwidth, p->im + (2*h-1)*p->mwidth, 2*w); } struct ph1 {char id1[8]; char ww1[14]; char id2[20]; char id3[4*16+4]; short ww2; char id4[20]; char ww3[2*16+1]; char id5[4*16]; char idx[11*16]; } ; struct pcdword { uBYTE high,low; }; 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(source,ziel,anzahl) struct pcdhqt *source; struct myhqt *ziel; int *anzahl; {int i; struct pcdquad *sub; struct myhqt *help; *anzahl=(source->entries)+1; for(i=0;i<*anzahl;i++) {sub = (struct pcdquad *)(((uBYTE *)source)+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_EXTRA 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 } static struct myhqt myhuffl[256],myhuff1[256],myhuff2[256]; static int myhufflenl=0,myhufflen1=0,myhufflen2=0; void readhqt(w,h,n, NeXT_fin) dim w,h; int n; FILE *NeXT_fin; { uBYTE *ptr; melde("readhqt\n"); if(READBUF_NeXT < 1) error(E_READ); ptr = sbuffer; readhqtsub((struct pcdhqt *)ptr,myhuffl,&myhufflenl); if(n<2) return; ptr+= 1 + 4* myhufflenl; readhqtsub((struct pcdhqt *)ptr,myhuff1,&myhufflen1); if(n<3) return; ptr+= 1 + 4* myhufflen1; readhqtsub((struct pcdhqt *)ptr,myhuff2,&myhufflen2); } void decode(w,h,f,f1,f2, autosync, NeXT_fin) dim w,h; implane *f,*f1,*f2; int autosync; FILE *NeXT_fin; {int i,htlen,sum; unsigned long sreg,maxwidth; unsigned int inh,n,zeile,segment,ident; struct myhqt *htptr,*hp; uBYTE *nptr; uBYTE *lptr; melde("decode\n"); #define nextbuf { nptr=sbuffer; if(READBUF_NeXT < 1) error(E_READ); } #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;\ }\ } if((!f) || (!f->im)) error(E_INTERN); if((f->iheight < h) || (f->iwidth<w)) error(E_INTERN); htlen=sreg=maxwidth=0; htptr=0; nextbuf; inh=32; lptr=0; shiftout(16); shiftout(16); n=0; for(;;) { if((sreg & 0xffffff00) == 0xfffffe00) {shiftout(24); ident=sreg>>16; shiftout(16); zeile=(ident>>1) & 0x1fff; segment=ident>>14; #ifdef DEBUG_EXTRA fprintf(stderr,"Ident %4x Zeile: %6d Segment %3d Pixels bisher: %d\n", ident,zeile,segment,n); #endif if(lptr && (n!=maxwidth)) error(E_SEQ1); n=0; if(zeile==h) return; if(zeile > h) error(E_SEQ2); switch(segment) { case 0: if(!f) error(E_SEQ7); lptr=f->im + zeile*f->mwidth; maxwidth=f->iwidth; htlen=myhufflenl; htptr=myhuffl; break; case 2: if(!f1) error(E_SEQ7); lptr=f1->im + (zeile>>1)*f1->mwidth; maxwidth=f1->iwidth; htlen=myhufflen1; htptr=myhuff1; break; case 3: if(!f2) error(E_SEQ7); lptr=f2->im + (zeile>>1)*f2->mwidth; maxwidth=f2->iwidth; htlen=myhufflen2; htptr=myhuff2; break; default:error(E_SEQ3); } } else { /* if((!lptr) || (n>maxwidth)) error(E_SEQ4);*/ if(!lptr) error(E_SEQ6); if(n>maxwidth) error(E_SEQ4); for(i=0,hp=htptr;(i<htlen) && ((sreg & hp->mask)!= hp->seq); i++,hp++); if(i>=htlen) error(E_SEQ5); sum=((int)(*lptr)) + ((char)hp->key); NORM(sum); *(lptr++) = sum; n++; shiftout(hp->len); } } }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.