home *** CD-ROM | disk | FTP | other *** search
-
- /* 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);
-
- }
-
- }
-
-
-
- }
-
-