home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
rtsi.com
/
2014.01.www.rtsi.com.tar
/
www.rtsi.com
/
OS9
/
OSK
/
NETWORK
/
netpbm_src.lzh
/
NETPBM
/
PPM
/
hpcdtoppm.c
< prev
next >
Wrap
C/C++ Source or Header
|
1996-11-18
|
35KB
|
1,428 lines
/* hpcdtoppm (Hadmut's pcdtoppm) v0.3
* 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 OWN_WRITE either here or by compiler-option if you don't want to use
the pbmplus-routines for writing */
#define xOWN_WRITE
/* 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
#ifndef OWN_WRITE
#include "ppm.h"
#else
/* 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 <stdio.h>
/* The header for the ppm-files */
#define PPM_Header "P6\n%d %d\n255\n"
#endif
/*
** Important: sBYTE must be a signed byte type !!!
**
*/
#ifndef sBYTE
#ifndef VMS
typedef signed char sBYTE;
#else
typedef char sBYTE;
#endif
#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,E_OVSKIP,
E_TAUTO,E_TCANT };
enum TURNS { T_NONE,T_RIGHT,T_LEFT,T_AUTO };
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;
#define nullplane ((implane *) 0)
struct pcdquad { uBYTE len,highseq,lowseq,key;};
struct pcdhqt { uBYTE entries; struct pcdquad entry[256];};
struct myhqt { unsigned long seq,mask,len; uBYTE key; };
static void error ARGS((enum ERRORS e));
static void planealloc ARGS((implane *p, dim width, dim height));
static enum ERRORS readplain ARGS((dim w, dim h, implane *l, implane *c1, implane *c2));
static void interpolate ARGS((implane *p));
static void halve ARGS((implane *p));
static void ycctorgb ARGS((dim w, dim h, implane *l, implane *c1, implane *c2));
static void writepicture ARGS((dim w, dim h, implane *r, implane *g, implane *b, enum TURNS t));
static void druckeid ARGS((void));
static void clear ARGS((implane *l, int n));
static long Skip4Base ARGS((void));
static void readhqt ARGS((dim w, dim h, int n));
static void decode ARGS((dim w, dim h, implane *f, implane *f1, implane *f2, int autosync));
static void sharpit ARGS((implane *l));
static void readhqtsub ARGS((struct pcdhqt *source, struct myhqt *ziel, int *anzahl));
static int testbegin ARGS((void));
static FILE *fin=0,*fout=0;
static char *pcdname=0,*ppmname=0;
static char nbuf[100];
static uBYTE sbuffer[SECSIZE];
static int do_sharp,keep_ycc;
/* Using preprocessor for inline-procs */
#ifdef DEBUG
static long bufpos;
#define SEEK(x) { if (fseek(fin,((x) * SECSIZE),0)) error(E_READ);\
fprintf(stderr,"S-Position %x\n",ftell(fin)); }
#define RPRINT {fprintf(stderr,"R-Position %x\n",ftell(fin));}
#define READBUF (bufpos=ftell(fin),fread(sbuffer,sizeof(sbuffer),1,fin))
#else
#define SEEK(x) { if (fseek(fin,((x) * SECSIZE),0)) error(E_READ);}
#define RPRINT
#define READBUF fread(sbuffer,sizeof(sbuffer),1,fin)
#endif
#ifdef MELDUNG
#define melde(x) fprintf(stderr,x)
#else
#define melde(x)
#endif
#define EREADBUF {if(READBUF < 1) error(E_READ);}
#define SKIP(n) { if (fseek(fin,(n),1)) error(E_READ);}
#define SKIPr(n) { if (fseek(fin,(n),1)) return(E_READ);}
#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;}
static 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,"Error in Arguments !\n\n");
fprintf(stderr,"Usage: hpcdtoppm [options] pcd-file [ppm-file]\n\n");
fprintf(stderr,"Opts:\n");
fprintf(stderr," -x Overskip mode (tries to improve color quality.)\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\n");
fprintf(stderr," -r Rotate clockwise for portraits\n");
fprintf(stderr," -l Rotate counter-clockwise for portraits\n");
fprintf(stderr," -a Try to find out orientation automatically.\n");
fprintf(stderr," (Experimentally, please report if it doesn't work.)\n\n");
fprintf(stderr," -ycc suppress ycc to rgb conversion \n");
fprintf(stderr," (Experimentally, doesn't have deeper sense)\n\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");
fprintf(stderr,"\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;
case E_OVSKIP: fprintf(stderr,"Can't read this resolution in overskip-mode\n"); break;
case E_TAUTO: fprintf(stderr,"Can't determine the orientation in overview mode\n");break;
case E_TCANT: fprintf(stderr,"Sorry, can't determine orientation for this file.\n");
fprintf(stderr,"Please give orientation parameters. \n");break;
default: fprintf(stderr,"Unknown error %d ???\n",e);break;
}
if(fin) fclose(fin);
if(fout && ppmname) fclose(fout);
exit(9);
}
static 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);
}
int
main(argc,argv)
int argc;
char **argv;
#define ASKIP { argc--; argv ++;}
{int bildnr;
char *opt;
dim w,h;
long cd_offset,cd_offhelp;
int do_info,do_diff,do_overskip;
enum TURNS turn=T_NONE;
enum SIZES size=S_UNSPEC;
enum ERRORS eret;
implane Luma, Chroma1,Chroma2;
ppm_init(&argc, argv);
do_info=do_diff=do_overskip=do_sharp=keep_ycc=0;
ASKIP;
while((argc>0) && **argv=='-')
{
opt= (*argv)+1;
ASKIP;
if(!strcmp(opt,"r"))
{if (turn == T_NONE) turn=T_RIGHT;
else error(E_ARG);
continue;
}
if(!strcmp(opt,"l"))
{if (turn == T_NONE) turn=T_LEFT;
else error(E_ARG);
continue;
}
if(!strcmp(opt,"a"))
{if (turn == T_NONE) turn=T_AUTO;
else error(E_ARG);
continue;
}
if(!strcmp(opt,"i"))
{ if (!do_info) do_info=1;
else error(E_ARG);
continue;
}
if(!strcmp(opt,"d"))
{ if (!do_diff) do_diff=1;
else error(E_ARG);
continue;
}
if(!strcmp(opt,"s"))
{ if (!do_sharp) do_sharp=1;
else error(E_ARG);
continue;
}
if(!strcmp(opt,"x"))
{ if (!do_overskip) do_overskip=1;
else error(E_ARG);
continue;
}
if(!strcmp(opt,"ycc"))
{ if (!keep_ycc) keep_ycc=1;
else error(E_ARG);
continue;
}
if((!strcmp(opt,"Base/16")) || (!strcmp(opt,"1")) || (!strcmp(opt,"128x192")))
{ if (size == S_UNSPEC) size = S_Base16;
else error(E_ARG);
continue;
}
if((!strcmp(opt,"Base/4" )) || (!strcmp(opt,"2")) || (!strcmp(opt,"256x384")))
{ if (size == S_UNSPEC) size = S_Base4;
else error(E_ARG);
continue;
}
if((!strcmp(opt,"Base" )) || (!strcmp(opt,"3")) || (!strcmp(opt,"512x768")))
{ if (size == S_UNSPEC) size = S_Base;
else error(E_ARG);
continue;
}
if((!strcmp(opt,"4Base" )) || (!strcmp(opt,"4")) || (!strcmp(opt,"1024x1536")))
{ if (size == S_UNSPEC) size = S_4Base;
else error(E_ARG);
continue;
}
if((!strcmp(opt,"16Base" )) || (!strcmp(opt,"5")) || (!strcmp(opt,"2048x3072")))
{ if (size == S_UNSPEC) size = S_16Base;
else error(E_ARG);
continue;
}
if((!strcmp(opt,"Overview" )) || (!strcmp(opt,"0")) || (!strcmp(opt,"O")))
{ if (size == S_UNSPEC) size = S_Over;
else error(E_ARG);
continue;
}
fprintf(stderr,"Unknown option: -%s\n",opt);
error(E_ARG);
}
if(size==S_UNSPEC) size=S_DEFAULT;
if(argc<1) error(E_ARG);
pcdname= *argv;
ASKIP;
if(argc>0)
{ppmname= *argv;
ASKIP;
}
if(argc>0) error(E_ARG);
if((size==S_Over) && (!ppmname)) error(E_ARG);
if(do_info && (size==S_Over)) error(E_OPT);
if(do_overskip && do_diff) error(E_OPT);
if(do_diff && (size != S_4Base) && (size != S_16Base)) error(E_OPT);
if(do_overskip && (size != S_Base16) && (size != S_Base4) && (size != S_Base) && (size != S_4Base) ) error(E_OVSKIP);
if((turn==T_AUTO)&&(size==S_Over)) error(E_TAUTO);
if(!(fin=fopen(pcdname,"r"))) error(E_READ);
if(do_info || (turn==T_AUTO))
{ SEEK(1);
EREADBUF;
}
if(turn==T_AUTO)
{
switch(sbuffer[0xe02 & 0x7ff]&0x03)
{case 0x00: turn=T_NONE; break;
case 0x01: turn=T_LEFT; break;
case 0x03: turn=T_RIGHT; break;
default: error(E_TCANT);
}
}
if(do_info) druckeid();
switch(size)
{
case S_Base16: w=BaseW/4;
h=BaseH/4;
planealloc(&Luma ,w,h);
planealloc(&Chroma1,w,h);
planealloc(&Chroma2,w,h);
if(!do_overskip)
{ SEEK(L_Head+1);
error(readplain(w,h,&Luma,&Chroma1,&Chroma2));
interpolate(&Chroma1);
interpolate(&Chroma2);
}
else
{ SEEK(L_Head+1);
error(readplain(w,h,&Luma,nullplane,nullplane));
SEEK(L_Head+L_Base16+1);
error(readplain(2*w,2*h,nullplane,&Chroma1,&Chroma2));
}
ycctorgb(w,h,&Luma,&Chroma1,&Chroma2);
/* Now Luma holds red, Chroma1 hold green, Chroma2 holds blue */
if(!ppmname) fout=stdout;
else
{if (!(fout=fopen(ppmname,"w"))) error(E_WRITE);
}
writepicture(w,h,&Luma,&Chroma1,&Chroma2,turn);
break;
case S_Base4: w=BaseW/2;
h=BaseH/2;
planealloc(&Luma ,w,h);
planealloc(&Chroma1,w,h);
planealloc(&Chroma2,w,h);
if(!do_overskip)
{ SEEK(L_Head+L_Base16+1);
error(readplain(w,h,&Luma,&Chroma1,&Chroma2));
interpolate(&Chroma1);
interpolate(&Chroma2);
}
else
{ SEEK(L_Head+L_Base16+1);
error(readplain(w,h,&Luma,nullplane,nullplane));
SEEK(L_Head+L_Base16+L_Base4+1);
error(readplain(2*w,2*h,nullplane,&Chroma1,&Chroma2));
}
ycctorgb(w,h,&Luma,&Chroma1,&Chroma2);
/* Now Luma holds red, Chroma1 hold green, Chroma2 holds blue */
if(!ppmname) fout=stdout;
else
{if (!(fout=fopen(ppmname,"w"))) error(E_WRITE);
}
writepicture(w,h,&Luma,&Chroma1,&Chroma2,turn);
break;
case S_Base: w=BaseW;
h=BaseH;
if(!do_overskip)
{ planealloc(&Luma ,w,h);
planealloc(&Chroma1,w,h);
planealloc(&Chroma2,w,h);
SEEK(L_Head+L_Base16+L_Base4+1);
error(readplain(w,h,&Luma,&Chroma1,&Chroma2));
interpolate(&Chroma1);
interpolate(&Chroma2);
}
else
{ planealloc(&Luma , w, h);
planealloc(&Chroma1,2*w,2*h);
planealloc(&Chroma2,2*w,2*h);
SEEK(L_Head+L_Base16+L_Base4+1);
error(readplain(w,h,&Luma,&Chroma1,&Chroma2));
interpolate(&Chroma1);
interpolate(&Chroma2);
interpolate(&Chroma1);
interpolate(&Chroma2);
cd_offset=Skip4Base();
SEEK(cd_offset+10); EREADBUF; cd_offhelp=(((long)sbuffer[2])<<8)|sbuffer[3];
SEEK(cd_offset+12); readhqt(w,h,3);
SEEK(cd_offset+cd_offhelp); decode(4*w,4*h,nullplane,&Chroma1,&Chroma2,1);
halve(&Chroma1);
halve(&Chroma2);
}
ycctorgb(w,h,&Luma,&Chroma1,&Chroma2);
/* Now Luma holds red, Chroma1 hold green, Chroma2 holds blue */
if(!ppmname) fout=stdout;
else
{if (!(fout=fopen(ppmname,"w"))) error(E_WRITE);
}
writepicture(w,h,&Luma,&Chroma1,&Chroma2,turn);
break;
case S_4Base: w=BaseW*2;
h=BaseH*2;
planealloc(&Luma,w,h);
planealloc(&Chroma1,w,h);
planealloc(&Chroma2,w,h);
if(!do_overskip)
{SEEK(L_Head+L_Base16+L_Base4+1);
error(readplain(w/2,h/2,&Luma,&Chroma1,&Chroma2));
interpolate(&Luma);
interpolate(&Chroma1);
interpolate(&Chroma1);
interpolate(&Chroma2);
interpolate(&Chroma2);
if(do_diff) {clear(&Luma,128);clear(&Chroma1,156);clear(&Chroma2,137);}
cd_offset = L_Head + L_Base16 + L_Base4 + L_Base ;
SEEK(cd_offset + 4); readhqt(w,h,1);
SEEK(cd_offset + 5); decode(w,h,&Luma,nullplane,nullplane,0);
}
else
{SEEK(L_Head+L_Base16+L_Base4+1);
error(readplain(w/2,h/2,&Luma,&Chroma1,&Chroma2));
interpolate(&Luma);
interpolate(&Chroma1);
interpolate(&Chroma1);
interpolate(&Chroma2);
interpolate(&Chroma2);
cd_offset = L_Head + L_Base16 + L_Base4 + L_Base ;
SEEK(cd_offset + 4); readhqt(w,h,1);
SEEK(cd_offset + 5); decode(w,h,&Luma,nullplane,nullplane,0);
cd_offset=ftell(fin);if(cd_offset % SECSIZE) error(E_POS);cd_offset/=SECSIZE;
SEEK(cd_offset+10); EREADBUF; cd_offhelp=(((long)sbuffer[2])<<8)|sbuffer[3];
SEEK(cd_offset+12); readhqt(w,h,3);
SEEK(cd_offset+cd_offhelp); decode(2*w,2*h,nullplane,&Chroma1,&Chroma2,1);
}
ycctorgb(w,h,&Luma,&Chroma1,&Chroma2);
/* Now Luma holds red, Chroma1 hold green, Chroma2 holds blue */
if(!ppmname) fout=stdout;
else
{if (!(fout=fopen(ppmname,"w"))) error(E_WRITE);
}
writepicture(w,h,&Luma,&Chroma1,&Chroma2,turn);
break;
case S_16Base: w=BaseW*4;
h=BaseH*4;
planealloc(&Luma,w,h);
planealloc(&Chroma1,w,h);
planealloc(&Chroma2,w,h);
SEEK(L_Head+L_Base16+L_Base4+1);
error(readplain(w/4,h/4,&Luma,&Chroma1,&Chroma2));
interpolate(&Luma);
interpolate(&Chroma1);
interpolate(&Chroma1);
interpolate(&Chroma2);
interpolate(&Chroma2);
cd_offset = L_Head + L_Base16 + L_Base4 + L_Base ;
SEEK(cd_offset + 4); readhqt(w/2,h/2,1);
SEEK(cd_offset + 5); decode(w/2,h/2,&Luma,nullplane,nullplane,0);
interpolate(&Luma);
if(do_diff) {clear(&Luma,128);clear(&Chroma1,156);clear(&Chroma2,137);}
cd_offset=ftell(fin);if(cd_offset % SECSIZE) error(E_POS);cd_offset/=SECSIZE;
SEEK(cd_offset+12); readhqt(w,h,3);
SEEK(cd_offset+14); decode(w,h,&Luma,&Chroma1,&Chroma2,0);
interpolate(&Chroma1);
interpolate(&Chroma2);
ycctorgb(w,h,&Luma,&Chroma1,&Chroma2);
/* Now Luma holds red, Chroma1 hold green, Chroma2 holds blue */
if(!ppmname) fout=stdout;
else
{if (!(fout=fopen(ppmname,"w"))) error(E_WRITE);
}
writepicture(w,h,&Luma,&Chroma1,&Chroma2,turn);
break;
case S_Over: w=BaseW/4;
h=BaseH/4;
planealloc(&Luma ,w,h);
planealloc(&Chroma1,w,h);
planealloc(&Chroma2,w,h);
for(bildnr=0;!feof(fin);bildnr++)
{
SEEK(5+SeBase16*bildnr);
eret=readplain(w,h,&Luma,&Chroma1,&Chroma2);
if(eret==E_READ) break;
error(eret);
interpolate(&Chroma1);
interpolate(&Chroma2);
ycctorgb(w,h,&Luma,&Chroma1,&Chroma2);
/* Now Luma holds red, Chroma1 hold green, Chroma2 holds blue */
sprintf(nbuf,"%s%04d",ppmname,bildnr+1);
if (!(fout=fopen(nbuf,"w"))) error(E_WRITE);
writepicture(w,h,&Luma,&Chroma1,&Chroma2,turn);
}
break;
default: error(E_INTERN);
}
exit(0);
}
#undef ASKIP
static enum ERRORS readplain(w,h,l,c1,c2)
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);
}
RPRINT;
return E_NONE;
}
static 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;
}
optr=p->im + (2*h-2)*p->mwidth;
nptr=p->im + (2*h-1)*p->mwidth;
for(x=0;x<w;x++)
{ *(nptr++) = *(optr++); *(nptr++) = *(optr++); }
}
static void halve(p)
implane *p;
{dim w,h,x,y;
uBYTE *optr,*nptr;
melde("halve\n");
if ((!p) || (!p->im)) error(E_INTERN);
w=p->iwidth/=2;
h=p->iheight/=2;
for(y=0;y<h;y++)
{
nptr=(p->im) + y*(p->mwidth);
optr=(p->im) + 2*y*(p->mwidth);
for(x=0;x<w;x++,nptr++,optr+=2)
{ *nptr = *optr;
}
}
}
#define BitShift 12
static void ycctorgb(w,h,l,c1,c2)
dim w,h;
implane *l,*c1,*c2;
{dim x,y;
uBYTE *pl,*pc1,*pc2;
long red,green,blue,i;
long L;
static int init=0;
static long XL[256],XC1[256],XC2[256],XC1g[256],XC2g[256];
melde("ycctorgb\n");
if((!l ) || ( l->iwidth != w ) || ( l->iheight != h) || (! l->im)) error(E_INTERN);
if((!c1) || (c1->iwidth != w ) || (c1->iheight != h) || (!c1->im)) error(E_INTERN);
if((!c2) || (c2->iwidth != w ) || (c2->iheight != h) || (!c2->im)) error(E_INTERN);
if(do_sharp) sharpit(l);
if(keep_ycc) return;
if(!init)
{init=1;
for(i=0;i<256;i++)
{ XL[i]= 5564 * i + 2048;
XC1[i]= 9085 * i - 1417185;
XC2[i]= 7461 * i - 1022138;
XC1g[i]= 274934 - 1762 * i;
XC2g[i]= 520268 - 3798 * i;
}
}
for(y=0;y<h;y++)
{
pl = l->im + y * l->mwidth;
pc1= c1->im + y * c1->mwidth;
pc2= c2->im + y * c2->mwidth;
for(x=0;x<w;x++)
{
L = XL[*pl];
red =(L + XC2[*pc2] )>>BitShift;
green=(L + XC1g[*pc1] + XC2g[*pc2] )>>BitShift;
blue =(L + XC1[*pc1] )>>BitShift;
NORM(red);
NORM(green);
NORM(blue);
*(pl++ )=red;
*(pc1++)=green;
*(pc2++)=blue;
}
}
}
#undef BitShift
static void writepicture(w,h,r,g,b,t)
dim w,h;
implane *r,*g,*b;
enum TURNS t;
{dim x,y;
register uBYTE *pr,*pg,*pb;
#ifndef OWN_WRITE
pixel *pixrow;
register pixel* pP;
#else
static uBYTE BUF[own_BUsize],*BUptr;
int BUcount;
#define BUinit {BUcount=0;BUptr=BUF;}
#define BUflush {fwrite(BUF,BUcount*3,1,fout);BUinit; }
#define BUwrite(r,g,b) {if(BUcount>=own_BUsize/3) BUflush; *BUptr++ = r ; *BUptr++ = g ; *BUptr++ = b ; BUcount++;}
#endif
melde("writepicture\n");
if((!r) || (r->iwidth != w ) || (r->iheight != h) || (!r->im)) error(E_INTERN);
if((!g) || (g->iwidth != w ) || (g->iheight != h) || (!g->im)) error(E_INTERN);
if((!b) || (b->iwidth != w ) || (b->iheight != h) || (!b->im)) error(E_INTERN);
switch (t)
{ case T_NONE:
#ifndef OWN_WRITE
ppm_writeppminit(fout,w,h,(pixval) 255, 0);
pixrow = ppm_allocrow( w );
for(y=0;y<h;y++)
{
pr= r->im + y * r->mwidth;
pg= g->im + y * g->mwidth;
pb= b->im + y * b->mwidth;
for(pP= pixrow,x=0;x<w;x++)
{
PPM_ASSIGN(*pP,((int)*pr),((int)*pg),((int)*pb));
pP++; pr++; pg++; pb++;
}
ppm_writeppmrow( fout, pixrow, w, (pixval) 255, 0 );
}
pm_close(fout);
#else
fprintf(fout,PPM_Header,w,h);
BUinit;
for(y=0;y<h;y++)
{
pr= r->im + y * r->mwidth;
pg= g->im + y * g->mwidth;
pb= b->im + y * b->mwidth;
for(x=0;x<w;x++) BUwrite(*pr++,*pg++,*pb++);
}
BUflush;
if(ppmname) fclose(fout);
#endif
break;
case T_RIGHT:
#ifndef OWN_WRITE
ppm_writeppminit(fout,h,w,(pixval) 255, 0);
pixrow = ppm_allocrow( h );
for(y=0;y<w;y++)
{
pr= r->im + r->mwidth * ( r->iheight - 1) + y;
pg= g->im + g->mwidth * ( g->iheight - 1) + y;
pb= b->im + b->mwidth * ( b->iheight - 1) + y;
for(pP= pixrow,x=0;x<h;x++)
{
PPM_ASSIGN(*pP,((int)*pr),((int)*pg),((int)*pb));
pP++; pr-= r->mwidth; pg-= g->mwidth; pb-= b->mwidth;
}
ppm_writeppmrow( fout, pixrow, h, (pixval) 255, 0 );
}
pm_close(fout);
#else
fprintf(fout,PPM_Header,h,w);
BUinit;
for(y=0;y<w;y++)
{
pr= r->im + r->mwidth * ( r->iheight - 1) + y;
pg= g->im + g->mwidth * ( g->iheight - 1) + y;
pb= b->im + b->mwidth * ( b->iheight - 1) + y;
for(x=0;x<h;x++)
{BUwrite(*pr,*pg,*pb);
pr-= r->mwidth; pg-= g->mwidth; pb-= b->mwidth;
}
}
BUflush;
if(ppmname) fclose(fout);
#endif
break;
case T_LEFT:
#ifndef OWN_WRITE
ppm_writeppminit(fout,h,w,(pixval) 255, 0);
pixrow = ppm_allocrow( h );
for(y=0;y<w;y++)
{
pr= r->im + r->iwidth - 1 - y;
pg= g->im + g->iwidth - 1 - y;
pb= b->im + b->iwidth - 1 - y;
for(pP= pixrow,x=0;x<h;x++)
{
PPM_ASSIGN(*pP,((int)*pr),((int)*pg),((int)*pb));
pP++; pr+= r->mwidth; pg+= g->mwidth; pb+= b->mwidth;
}
ppm_writeppmrow( fout, pixrow, h, (pixval) 255, 0 );
}
pm_close(fout);
#else
fprintf(fout,PPM_Header,h,w);
BUinit;
for(y=0;y<w;y++)
{
pr= r->im + r->iwidth - 1 - y;
pg= g->im + g->iwidth - 1 - y;
pb= b->im + b->iwidth - 1 - y;
for(x=0;x<h;x++)
{BUwrite(*pr,*pg,*pb);
pr+= r->mwidth; pg+= g->mwidth; pb+= b->mwidth;
}
}
BUflush;
if(ppmname) fclose(fout);
#endif
break;
default: error(E_INTERN);
}
}
struct ph1
{char id1[8];
uBYTE ww1[14];
char id2[20];
char id3[4*16+4];
short ww2;
char id4[20];
uBYTE ww3[2*16+1];
char id5[4*16];
uBYTE idx[11*16];
} ;
static void druckeid()
{int i;
struct ph1 *d;
char ss[100];
d=(struct ph1 *)sbuffer;
#define dr(feld,kennung) \
strncpy(ss,feld,sizeof(feld));\
ss[sizeof(feld)]=0;\
fprintf(stderr,"%s: %s \n",kennung,ss);
#define db(feld) fprintf(stderr,"--%d\n",sizeof(feld)); for(i=0;i<sizeof(feld);i+=2) \
fprintf(stderr,"%4d %6d\n",i,(signed int)((((unsigned int)feld[i])<<8)|feld[i+1]));\
fprintf(stderr,"\n");
dr(d->id1,"Id1")
dr(d->id2,"Id2")
dr(d->id3,"Id3")
dr(d->id4,"Id4")
dr(d->id5,"Id5")
/*
db(d->ww1)
db(d->ww3)
db(d->idx)
*/
#undef dr
#undef db
}
struct pcdword
{ uBYTE high,low;
};
static int lpt[1024];
static void readlpt(w,h)
dim w,h;
{int i;
struct pcdword *ptr;
EREADBUF;
ptr = (struct pcdword *)sbuffer;
for(i=0;i<h/4;i++,ptr++)
{lpt[i] = ((int)ptr->high)<<8 | ptr->low ;
}
}
#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
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;
static 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);
}
static void decode(w,h,f,f1,f2,autosync)
dim w,h;
implane *f,*f1,*f2;
int autosync;
{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; 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 seeksync { while (!issync) shiftout(1);}
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;
htptr=0;
nextbuf;
inh=32;
lptr=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;
#ifdef DEBUG
fprintf(stderr,"Ident %4x Zeile: %6d Segment %3d Pixels bisher: %5d Position: %8lx\n",
ident,zeile,segment,n,bufpos);
#endif
if(lptr && (n!=maxwidth)) error(E_SEQ1);
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;
htlen=myhufflen0;
htptr=myhuff0;
break;
case 2: if((!f1) && autosync) {seeksync; break;}
if(!f1) error(E_SEQ7);
lptr=f1->im + (zeile>>1)*f1->mwidth;
maxwidth=f1->iwidth;
htlen=myhufflen1;
htptr=myhuff1;
break;
case 3: if((!f2) && autosync) {seeksync; break;}
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)) + ((sBYTE)hp->key);
NORM(sum);
*(lptr++) = sum;
n++;
shiftout(hp->len);
}
}
#undef nextbuf
#undef checkbuf
#undef shiftout
#undef issync
#undef seeksync
}
static void clear(l,n)
implane *l;
int n;
{ dim x,y;
uBYTE *ptr;
ptr=l->im;
for (x=0;x<l->mwidth;x++)
for (y=0; y<l->mheight;y++)
*(ptr++)=n;
}
#define slen 3072
static void sharpit(l)
implane *l;
{int x,y,h,w,mw,akk;
uBYTE f1[slen],f2[slen],*old,*akt,*ptr,*work,*help,*optr;
if((!l) || (!l->im)) error(E_INTERN);
if(l->iwidth > slen) error(E_INTERN);
old=f1; akt=f2;
h=l->iheight;
w=l->iwidth;
mw=l->mwidth;
for(y=1;y<h-1;y++)
{
ptr=l->im+ y*mw;
optr=ptr-mw;
work=akt;
*(work++)= *(ptr++);
for(x=1;x<w-1;x++)
{ akk = 5*((int)ptr[0])- ((int)ptr[1]) - ((int)ptr[-1])
- ((int)ptr[mw]) - ((int)ptr[-mw]);
NORM(akk);
*(work++)=akk;
ptr++;
}
*(work++)= *(ptr++);
if(y>1) memcpy(optr,old,w);
help=old;old=akt;akt=help;
}
akt=optr+mw;
for(x=0;x<w;x++)
*(akt++) = *(old++);
}
#undef slen
static int testbegin()
{int i,j;
for(i=j=0;i<32;i++)
if(sbuffer[i]==0xff) j++;
return (j>30);
}
static long Skip4Base()
{long cd_offset,cd_offhelp;
cd_offset = L_Head + L_Base16 + L_Base4 + L_Base ;
SEEK(cd_offset+3);
EREADBUF;
cd_offhelp=(((long)sbuffer[510])<<8)|sbuffer[511] + 1;
cd_offset+=cd_offhelp;
SEEK(cd_offset);
EREADBUF;
while(!testbegin())
{cd_offset++;
EREADBUF;
}
return cd_offset;
}