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.