home *** CD-ROM | disk | FTP | other *** search
- /* hpcdtoppm (Hadmut's pcdtoppm) v0.6.beta
- * Copyright (c) 1992, 1993, 1994 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"
- #define DITH_NEUTR 128
-
- FLTPT PAPER_LEFT =DEF_PAPER_LEFT;
- FLTPT PAPER_BOTTOM =DEF_PAPER_BOTTOM;
- FLTPT PAPER_WIDTH =DEF_PAPER_WIDTH;
- FLTPT PAPER_HEIGHT =DEF_PAPER_HEIGHT;
- FLTPT PRINTER_XDPI =DEF_DPI;
- FLTPT PRINTER_YDPI =DEF_DPI;
- FLTPT PRINTER_FAK =1.0;
- sINT PSIZE_SET=0,DPI_SET=0,FAK_SET=0;
-
-
- static char pshdr[]="%%Creator: hpcdtoppm v0.6.beta\n";
- static char hex[]="0123456789ABCDEF";
- #define HEX(x) {fputc(hex[((x)>>4)&0xf],fout);fputc(hex[(x)&0xf],fout);}
-
-
- /* find an appropriate scaling coefficient and generate a ps header
- * including a BoundingBox comment and a translate/scale sequence to
- * fit the pixw*pixh image into a square on paper with PS user coordinates
- * x,y,w,h
- */
- static void size_dependant(FILE *fout,sINT pixw,sINT pixh,
- FLTPT x,FLTPT y,FLTPT w,FLTPT h)
- { FLTPT scale=(FLTPT)w/pixw,scaley=(FLTPT)h/pixh;
-
- if(scale>scaley) scale=scaley;
- x+=w/2.0;y+=h/2.0;
- fprintf(fout,"%%%%BoundingBox: %.8g %.8g %.8g %.8g\n",
- x-scale*pixw/2.0,y-scale*pixh/2.0,
- x+scale*pixw/2.0,y+scale*pixh/2.0);
- fprintf(fout,"%s",pshdr);
- fputs("%%Pages: 1 1\n",fout);
-
- if(pcdname) fprintf(fout,"%%%%Title: %s\n",pcdname);
- fputs("%%EndComments\n\n",fout);
-
- fprintf(fout,"%f %f translate\n",x-scale*pixw/2.0,y-scale*pixh/2.0);
- fprintf(fout,"%f %f scale\n",scale*pixw,scale*pixh);
- }
-
-
-
- static void end_postscript(FILE *fout)
- {
- fputs("%%EOF\n\n",fout);
- }
-
-
-
-
- static void sub_psgrey(FILE *fout,dim w,dim h, uBYTE *ptr,sdim zeil,sdim pix)
- { dim x,y;
- register uBYTE *p;
- sINT c;
-
- size_dependant(fout,w,h,PAPER_LEFT,PAPER_BOTTOM,PAPER_WIDTH,PAPER_HEIGHT);
- fprintf(fout,"%d string\n",w);
- fprintf(fout,"%d %d 8\n",w,h); /* always 8 bit per channel */
- fprintf(fout,"[%d 0 0 %d 0 %d]\n",w,-h,h);
- fputs("{currentfile 1 index readhexstring pop} image\n",fout);
-
- c=0;
- for(y=0;y<h;y++,ptr+=zeil)
- for(p=ptr,x=0;x<w;x++,p+=pix)
- {HEX(*p);
- if(!(++c % 36)) fputs("\n",fout);
- }
-
- fputs("\npop\n\n",fout);
- }
-
-
-
-
-
-
-
- void write_epsgrey(FILE *fout,dim w,dim h, uBYTE *ptr,sdim zeil,sdim pix)
- {
- fputs("%!PS-Adobe-2.0 EPSF-2.0\n",fout);
- sub_psgrey(fout,w,h, ptr,zeil,pix);
- end_postscript(fout);
- }
-
- void write_psgrey(FILE *fout,dim w,dim h, uBYTE *ptr,sdim zeil,sdim pix)
- {
- fputs("%!PS-Adobe-2.0\n",fout);
- sub_psgrey(fout,w,h, ptr,zeil,pix);
- fputs("showpage\n",fout);
- end_postscript(fout);
- }
-
-
-
-
-
-
-
-
-
-
-
- static void sub_psrgb(FILE *fout,dim w,dim h,
- uBYTE *rptr,sdim rzeil,sdim rpix,
- uBYTE *gptr,sdim gzeil,sdim gpix,
- uBYTE *bptr,sdim bzeil,sdim bpix)
- { dim x,y;
- register uBYTE *pr,*pg,*pb;
- sINT c;
-
- size_dependant(fout,w,h,PAPER_LEFT,PAPER_BOTTOM,PAPER_WIDTH,PAPER_HEIGHT);
- fprintf(fout,"%d string\n",w*3);
- fprintf(fout,"%d %d 8\n",w,h); /* always 8 bit per channel */
- fprintf(fout,"[%d 0 0 %d 0 %d]\n",w,-h,h);
- fputs("{currentfile 1 index readhexstring pop} false 3 colorimage\n",fout);
-
- c=0;
- for(y=0;y<h;y++,rptr+=rzeil,gptr+=gzeil,bptr+=bzeil)
- for(pr=rptr,pg=gptr,pb=bptr,x=0;x<w;x++,pr+=rpix,pg+=gpix,pb+=bpix)
- {HEX(*pr);HEX(*pg);HEX(*pb);
- if(!(++c % 12)) fputs("\n",fout);
- }
-
- fputs("\npop\n\n",fout);
- }
-
-
- void write_epsrgb(FILE *fout,dim w,dim h,
- uBYTE *rptr,sdim rzeil,sdim rpix,
- uBYTE *gptr,sdim gzeil,sdim gpix,
- uBYTE *bptr,sdim bzeil,sdim bpix)
- {
- fputs("%!PS-Adobe-2.0 EPSF-2.0\n",fout);
- sub_psrgb(fout,w,h, rptr,rzeil,rpix,gptr,gzeil,gpix,bptr,bzeil,bpix);
- end_postscript(fout);
- }
-
-
-
- void write_psrgb(FILE *fout,dim w,dim h,
- uBYTE *rptr,sdim rzeil,sdim rpix,
- uBYTE *gptr,sdim gzeil,sdim gpix,
- uBYTE *bptr,sdim bzeil,sdim bpix)
- {
- fputs("%!PS-Adobe-2.0\n",fout);
- sub_psrgb(fout,w,h, rptr,rzeil,rpix,gptr,gzeil,gpix,bptr,bzeil,bpix);
- fputs("showpage\n",fout);
- end_postscript(fout);
- }
-
-
-
-
-
-
-
-
-
- typedef sINT dt;
- extern sINT dithtab[];
- #define DS 4
- #define DA (1<<(DS-1))
- #define DT 127
-
- static void fakcopy(dim worig,dim horig, uBYTE *ptr1,sdim zeil,sdim pix,
- sdim wx,sINT zn,dt *dest)
- {FLTPT owf,ohf,wbruch,hbruch,m1,m2,ha,hb;
- dim owd,ohd,x;
- uBYTE *ptr2;
- sINT md;
-
- ohf=zn/PRINTER_FAK;
- ohd=(dim)ohf;
- hbruch=ohf-(FLTPT)ohd;
- if(ohd>=horig) error(E_INTERN);
-
- ptr1+=zeil*ohd;
- ptr2= (ohd < horig - 1) ? ptr1+zeil : ptr1;
-
- dest[-1]=DITH_NEUTR;
-
- for(x=0;x<wx;x++)
- {owf=x/PRINTER_FAK;
- owd=(dim)owf;
- wbruch=owf-(FLTPT)owd;
- if(owd>=worig) error(E_INTERN);
-
- if(owd<worig-1)
- {ha=(FLTPT)ptr1[owd*pix];
- hb=(FLTPT)ptr1[(owd+1)*pix];
- m1=ha+wbruch*(hb-ha);
-
- ha=(FLTPT)ptr2[owd*pix];
- hb=(FLTPT)ptr2[(owd+1)*pix];
- m2=ha+wbruch*(hb-ha);
- }
- else
- { m1=(FLTPT)ptr1[owd*pix];
- m2=(FLTPT)ptr2[owd*pix];
- }
- md=(sINT)(m1+hbruch*(m2-m1));
- if(md<0 || md>255) {fprintf(stderr,"md %d\n",md); error(E_INTERN);}
- *(dest++)=dithtab[md];
-
- }
-
- dest[0]=DITH_NEUTR;
- }
-
- static void sub_psdith(FILE *fout,dim worig,dim horig, uBYTE *ptr,sdim zeil,sdim pix)
- { register uBYTE *p;
- sINT c,i,ii,j,reg,bit;
- dt new,diff;
- dt *dP1,*dP2,*akt,*nex,*help,*rrun;
- dim ww=0,wl=0,wr=0,hh=0,ho=0,hu=0,wx=0,hx=0;
- int ccase;
- FLTPT PW=0.0,PH=0.0;
-
- #define copy(n,d) {if(FAK_SET) fakcopy(worig,horig,ptr,zeil,pix,wx,n,d); \
- else{p=ptr+((n)*zeil); rrun=d;\
- for(ii=0;ii<wx;ii++,p+=pix,rrun++) *rrun = dithtab[*p]; \
- d[-1]=d[wx]=DITH_NEUTR; }}
-
-
- #define pr(x) { reg= (reg<<1) | x; bit++; \
- if(bit==8) {HEX(reg); \
- if(!(++c % 36)) fputs("\n",fout);\
- bit=reg=0;}}
-
- #define flush { while(bit) pr(1); }
- #define fill pr(1)
-
-
-
- #define MakeFit(wi,he) { ww=(wi+7) & (~7); wl=(ww-wi)/2; wr=ww-wi-wl; \
- hh=(he+7) & (~7); ho=(hh-he)/2; hu=hh-he-ho; }
-
-
-
- ccase=( FAK_SET ? 4 : 0 ) |
- ( DPI_SET ? 2 : 0 ) |
- ( PSIZE_SET ? 1 : 0 ) ;
-
-
- switch (ccase)
- {case 0: /* no option or -dpi option */
- case 2: hx=horig;
- wx=worig;
- MakeFit(wx,hx);
- PW=ww*72.0/PRINTER_XDPI;
- PH=hh*72.0/PRINTER_YDPI;
- break;
-
- case 1: /* paper size set with -pw and/or -ph */
- hx=horig;
- wx=worig;
- MakeFit(wx,hx);
- PW=PAPER_WIDTH;
- PH=PAPER_HEIGHT;
- break;
-
- case 6: /* -fak option (and perhaps -dpi) */
- case 4: hx=PRINTER_FAK*horig+0.5;
- wx=PRINTER_FAK*worig+0.5;
- MakeFit(wx,hx);
- PW=ww*72.0/PRINTER_XDPI;
- PH=hh*72.0/PRINTER_YDPI;
- break;
-
- case 5: /* -fak and papersize */
- hx=PRINTER_FAK*horig+0.5;
- wx=PRINTER_FAK*worig+0.5;
- MakeFit(wx,hx);
- PW=PAPER_WIDTH;
- PH=PAPER_HEIGHT;
- break;
-
- case 3: /* papersize and dpi set, probably the most important case */
- PW=PAPER_WIDTH;
- PH=PAPER_HEIGHT;
-
- FAK_SET=1;
- {FLTPT fw,fh;
- fw=PW/72.0*PRINTER_XDPI/worig;
- fh=PH/72.0*PRINTER_YDPI/horig;
- PRINTER_FAK=MIN(fw,fh);
- }
- hx=PRINTER_FAK*horig+0.5;
- wx=PRINTER_FAK*worig+0.5;
- MakeFit(wx,hx);
- PW=ww*72.0/PRINTER_XDPI;
- PH=hh*72.0/PRINTER_YDPI;
- break;
-
-
- case 7: /* size, dpi and factor set, this case should have been
- cought earlier... */
- default: error(E_INTERN);
- };
-
- if(FAK_SET && (PRINTER_FAK<=0.0 || PRINTER_FAK >=1000.0)) error(E_PRPAR);
- if(PW<=0.0 || PH<=0.0) error(E_PRPAR);
-
- if(wx < 4 || hx < 4) error(E_PRPAR);
-
-
- if (!(dP1=(dt *)malloc((wx+2)*sizeof(dt)))) error(E_MEM);
- if (!(dP2=(dt *)malloc((wx+2)*sizeof(dt)))) error(E_MEM);
-
-
-
- size_dependant(fout,ww,hh,PAPER_LEFT,PAPER_BOTTOM,PW,PH);
-
- fprintf(fout,"%d string\n",ww);
- fprintf(fout,"%d %d 1\n",ww,hh); /* always 8 bit per channel */
- fprintf(fout,"[%d 0 0 %d 0 %d]\n",ww,-hh,hh);
- fputs("{currentfile 1 index readhexstring pop} image\n",fout);
-
- c=bit=reg=0;
- akt=dP1+1;
- nex=dP2+1;
-
- for(i=0;i<ho;i++)
- for(j=0;j<ww;j++)
- fill;
-
- copy(0,nex);
- for(i=0;i<hx;i++)
- {help=akt; akt=nex; nex=help;
- if(i<hx-1) copy(i+1,nex);
-
- if(i&1)
- for(j=0;j<wx;j++)
- { new=akt[j]>DT ? 255 : 0;
- diff = akt[j]-new;
- akt[j]=new;
- akt[j+1]+=(diff*7 + DA)>>DS;
- nex[j+1]+=(diff + DA)>>DS;
- nex[j ]+=(diff*5 + DA)>>DS;
- nex[j-1]+=(diff*3 + DA)>>DS;
- }
- else
- for(j=wx-1;j>=0;j--)
- { new=akt[j]>DT ? 255 : 0;
- diff = akt[j]-new;
- akt[j]=new;
- akt[j-1]+=(diff*7 + DA)>>DS;
- nex[j-1]+=(diff + DA)>>DS;
- nex[j ]+=(diff*5 + DA)>>DS;
- nex[j+1]+=(diff*3 + DA)>>DS;
- }
-
-
- for(j=0;j<wl;j++) fill;
-
- for(j=0;j<wx;j++)
- {if (akt[j]>DT) { pr(1); }
- else { pr(0); }
- }
-
- for(j=0;j<wr;j++) fill;
-
- flush;
- }
-
- for(i=0;i<hu;i++)
- for(j=0;j<ww;j++)
- fill;
- flush;
-
- fputs("\npop\n\n",fout);
- free(dP1);
- free(dP2);
- }
-
-
- void write_epsdith(FILE *fout,dim w,dim h, uBYTE *ptr,sdim zeil,sdim pix)
- {
- fputs("%!PS-Adobe-2.0 EPSF-2.0\n",fout);
- sub_psdith(fout,w,h, ptr,zeil,pix);
- end_postscript(fout);
- }
-
- void write_psdith(FILE *fout,dim w,dim h, uBYTE *ptr,sdim zeil,sdim pix)
- {
- fputs("%!PS-Adobe-2.0\n",fout);
- sub_psdith(fout,w,h, ptr,zeil,pix);
- fputs("showpage\n",fout);
- end_postscript(fout);
- }
-
-
-
-