ftp.nice.ch/pub/next/tools/cdrom/pCD.0.34.N.bs.tar.gz#/pCD0.3.4/hpcdtoppm.0.4/main.c

This is main.c in view mode; [Download] [Up]

/* hpcdtoppm (Hadmut's pcdtoppm) v0.4
*  Copyright (c) 1992, 1993 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"

FILE  *fin=0,*fout=0;

uBYTE sbuffer[SECSIZE];

enum TURNS  turn     = T_UNSPEC;
enum SIZES  size     = S_UNSPEC;
enum OUTFOR outfor   = O_UNSPEC;
enum CORR   corrmode = C_UNSPEC;

int do_info,do_diff,do_overskip,do_sharp,monochrome;
int do_melde,do_rep,do_crop;
int flhori=0,flvert=0;
char *pcdname=0,*ppmname=0;



static implane Luma, Chroma1,Chroma2;
static implane *PLuma,*PChroma1,*PChroma2;
static int contsize=1;

static int print_pos;
#define PrintPos(x) {if(print_pos) fprintf(stderr,"File-Offset: %8ld = %8x (hex)\n",(long)(x),(unsigned int)(x));}

static void checkin();
static void parseargs();
static void f_1();
static void f_3();
static void f_4();
static void f_5();
static void f_ov();
static void f_co();



void close_all()
 {
  if(fin) fclose(fin);
  if(fout && ppmname) fclose(fout);

 }


void main(argc,argv)
  int argc;
  char **argv;
 {
  do_info=do_diff=do_overskip=do_sharp=monochrome=0;
  do_melde=do_rep=do_crop=0;
  print_pos=0;

  parseargs(argc,argv);

  if(size     == S_UNSPEC) size     = S_DEFAULT;
  if(outfor   == O_UNSPEC) outfor   = O_DEFAULT;
  if(corrmode == C_UNSPEC) corrmode = C_DEFAULT;
  if(turn     == T_UNSPEC) turn     = T_DEFAULT;

  monochrome=(outfor==O_PGM)||(outfor==O_PSG)||(outfor==O_EPSG);




  if((size==S_Over) && (!ppmname)) error(E_ARG);
  if((size==S_Contact) && do_crop) error(E_ARG);
  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(print_pos   && (size != S_Base16) && (size != S_Base4) && (size != S_Base) && (size != S_4Base) ) error(E_OPT);
  if(do_info     && (size != S_Base16) && (size != S_Base4) && (size != S_Base) && (size != S_4Base) ) error(E_OPT);
  if(monochrome && do_overskip) error(E_OPT);
  if((size==S_Contact) &&((contsize<1) || (contsize>100))) error(E_OPT);

  if(!(fin=fopen(pcdname,R_OP))) error(E_READ);



  if((size != S_Over) && (size != S_Contact)) checkin();

  PLuma=    &Luma;
  PChroma1= monochrome ? 0 : &Chroma1; 
  PChroma2= monochrome ? 0 : &Chroma2; 

  switch(size)
   {
    case S_Base16:  f_1(BaseW/4,BaseH/4,L_Head,(L_Head+L_Base16));
                    break;

    case S_Base4:   f_1(BaseW/2,BaseH/2,(L_Head+L_Base16),(L_Head+L_Base16+L_Base4));
                    break;

    case S_Base:    f_3(BaseW,BaseH,(L_Head+L_Base16+L_Base4));
                    break;

    case S_4Base:   f_4(BaseW*2,BaseH*2,(L_Head+L_Base16+L_Base4));
                    break;

    case S_16Base:  f_5(BaseW*4,BaseH*4);
                    break;

    case S_Over:    f_ov(BaseW/4,BaseH/4,5,SeBase16);
                    break;

    case S_Contact: f_co(BaseW/4,BaseH/4,5,SeBase16);
                    break;

    default: error(E_INTERN); 
   }

  close_all();
  exit(0);

 }





static void f_1(w,h,normal,overskip)
  dim w,h;
  int normal,overskip;
 {
  planealloc(PLuma   ,w,h);
  if (!monochrome) planealloc(PChroma1,w,h);
  if (!monochrome) planealloc(PChroma2,w,h);

  PrintPos(normal*SECSIZE);
  SEEK(normal+1);                   
      
  if(!do_overskip)
    { error(readplain(fin,w,h,PLuma,PChroma1,PChroma2));
      if (!monochrome) 
        {interpolate(PChroma1);
         interpolate(PChroma2);
        }
    }
  else
    { error(readplain(fin,w,h,PLuma,nullplane,nullplane));
      SEEK(overskip+1);
      error(readplain(fin,2*w,2*h,nullplane,PChroma1,PChroma2));
    }
   

  colconvert(&w,&h,PLuma,PChroma1,PChroma2);
  /* Now Luma holds red, Chroma1 hold green, Chroma2 holds blue */

  if(!ppmname) fout=stdout;
  else
   {if (!(fout=fopen(ppmname,W_OP))) error(E_WRITE);
   }
  writepicture(w,h,PLuma,PChroma1,PChroma2,turn);

 } 


static void f_3(w,h,normal)
  dim w,h;
  int normal;
 {long cd_offset,cd_offhelp;

  PrintPos(normal*SECSIZE);
  SEEK(normal+1);

  if(!do_overskip)
    { planealloc(PLuma   ,w,h);
      if (!monochrome) planealloc(PChroma1,w,h);
      if (!monochrome) planealloc(PChroma2,w,h);
      error(readplain(fin,w,h,PLuma,PChroma1,PChroma2));
      if (!monochrome) 
        {interpolate(PChroma1);
         interpolate(PChroma2);
        }
    }
  else
    { planealloc(PLuma   ,  w,  h);
      if (!monochrome) planealloc(PChroma1,2*w,2*h);
      if (!monochrome) planealloc(PChroma2,2*w,2*h);
      error(readplain(fin,w,h,PLuma,PChroma1,PChroma2));
      interpolate(PChroma1);
      interpolate(PChroma2);
      interpolate(PChroma1);
      interpolate(PChroma2);

      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,PChroma1,PChroma2,1);

      halve(PChroma1);
      halve(PChroma2);
    }
  colconvert(&w,&h,PLuma,PChroma1,PChroma2);
  /* Now Luma holds red, Chroma1 hold green, Chroma2 holds blue */

  if(!ppmname) fout=stdout;
  else
   {if (!(fout=fopen(ppmname,W_OP))) error(E_WRITE);
   }
  writepicture(w,h,PLuma,PChroma1,PChroma2,turn);


 }



static void f_4(w,h,normal)
  dim w,h;
  int normal;
 {long cd_offset,cd_offhelp;

  planealloc(PLuma,w,h);
  if (!monochrome) planealloc(PChroma1,w,h);
  if (!monochrome) planealloc(PChroma2,w,h);
  PrintPos((L_Head+L_Base16+L_Base4+L_Base)*SECSIZE);

  if(!do_overskip)
   {SEEK(L_Head+L_Base16+L_Base4+1);
    error(readplain(fin,w/2,h/2,PLuma,PChroma1,PChroma2));
    interpolate(PLuma);
    if (!monochrome) 
     {interpolate(PChroma1);
      interpolate(PChroma1);
      interpolate(PChroma2);
      interpolate(PChroma2);
     }

    if(do_diff) {clear(PLuma,neutrLum);clear(PChroma1,neutrCh1);clear(PChroma2,neutrCh2);}

    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,PLuma,nullplane,nullplane,0);
   }
  else
   {SEEK(L_Head+L_Base16+L_Base4+1);
    error(readplain(fin,w/2,h/2,PLuma,PChroma1,PChroma2));
    interpolate(PLuma);
    interpolate(PChroma1);
    interpolate(PChroma1);
    interpolate(PChroma2);
    interpolate(PChroma2);

    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,PLuma,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,PChroma1,PChroma2,1);
     
   }
  colconvert(&w,&h,PLuma,PChroma1,PChroma2);
  /* Now Luma holds red, Chroma1 hold green, Chroma2 holds blue */

  if(!ppmname) fout=stdout;
  else
   {if (!(fout=fopen(ppmname,W_OP))) error(E_WRITE);
   }
  writepicture(w,h,PLuma,PChroma1,PChroma2,turn);

 }



static void f_5(w,h)
  dim w,h;
 {long cd_offset;

  planealloc(PLuma,w,h);
  if (!monochrome) planealloc(PChroma1,w,h);
  if (!monochrome) planealloc(PChroma2,w,h);

  SEEK(L_Head+L_Base16+L_Base4+1);
  error(readplain(fin,w/4,h/4,PLuma,PChroma1,PChroma2));
  interpolate(PLuma);
  if(!monochrome)
   {interpolate(PChroma1);
    interpolate(PChroma1);
    interpolate(PChroma2);
    interpolate(PChroma2);
   }

  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,PLuma,nullplane,nullplane,0);
  interpolate(PLuma);

  if(do_diff) {clear(PLuma,neutrLum);clear(PChroma1,neutrCh1);clear(PChroma2,neutrCh2);}

  cd_offset=ftell(fin);
  if(cd_offset % SECSIZE) error(E_POS);
  PrintPos(cd_offset);
  cd_offset/=SECSIZE;

  SEEK(cd_offset+12);        readhqt(w,h,3);
  SEEK(cd_offset+14);        decode(w,h,PLuma,PChroma1,PChroma2,0);

  if(!monochrome)
   {interpolate(PChroma1);
    interpolate(PChroma2);
   }

  colconvert(&w,&h,PLuma,PChroma1,PChroma2);
  /* Now Luma holds red, Chroma1 hold green, Chroma2 holds blue */

  if(!ppmname) fout=stdout;
  else
   {if (!(fout=fopen(ppmname,W_OP))) error(E_WRITE);
   }
  writepicture(w,h,PLuma,PChroma1,PChroma2,turn);

 }




static void f_ov(w,h,offset,imsize)
  dim w,h;
  int offset,imsize;
 {int bildnr,bilder;
  dim wx,hx;
  enum ERRORS eret;
  enum TURNS imorient;
  char nbuf[100];

  wx=w; hx=h;

  planealloc(PLuma   ,w,h);
  if (!monochrome) planealloc(PChroma1,w,h);
  if (!monochrome) planealloc(PChroma2,w,h);

  SEEK(0); READBUF;
  bilder=(((int) sbuffer[10])<<8) | sbuffer[11];


  for(bildnr=0;bildnr<bilder;bildnr++)
   {
    w=wx;h=hx;
    PLuma->im=PLuma->mp;
    if(PChroma1) PChroma1->im=PChroma1->mp;
    if(PChroma2) PChroma2->im=PChroma2->mp;

    SEEK(offset+imsize*bildnr);
  
    eret=readplain(fin,w,h,PLuma,PChroma1,PChroma2);
    if(eret==E_READ) break;
    error(eret);

    if(!monochrome)
     {interpolate(PChroma1);
      interpolate(PChroma2);
     }

    colconvert(&w,&h,PLuma,PChroma1,PChroma2);
  
    sprintf(nbuf,"%s%04d",ppmname,bildnr+1);
    if (!(fout=fopen(nbuf,W_OP))) error(E_WRITE);
     switch(sbuffer[12+bildnr] & 3)
      {case 0:  imorient=T_NONE; break;
       case 1:  imorient=T_LEFT; break;
       case 3:  imorient=T_RIGHT; break;
       default: imorient=T_NONE;
      }
    writepicture(w,h,PLuma,PChroma1,PChroma2,turn != T_AUTO ? turn : imorient);
   }
 }




static void f_co(w,h,offset,imsize)
  dim w,h;
  int offset,imsize;
 {int bildnr,bilder,cols,rows,xstep,ystep,mw,mh;
  enum ERRORS eret;
  enum TURNS imorient;
  implane mLuma,mChroma1,mChroma2;
  implane *pmL,*pmCh1,*pmCh2;

  pmL=    &mLuma;
  pmCh1= monochrome ? 0 : &mChroma1; 
  pmCh2= monochrome ? 0 : &mChroma2; 


  SEEK(0); READBUF;
  bilder=(((int) sbuffer[10])<<8) | sbuffer[11];

  cols=contsize;
  rows=(bilder+cols-1)/cols;

  xstep=ystep=0;

  switch(turn)
   {case T_NONE: xstep=w;ystep=h; break;
    case T_RIGHT:
    case T_LEFT: xstep=h;ystep=w; break;
    case T_AUTO: xstep=ystep=w;   break;
    default: error(E_INTERN);
   }

  mw=cols*xstep;
  mh=rows*ystep;

  planealloc(PLuma   ,w,h);
  if (!monochrome) planealloc(PChroma1,w,h);
  if (!monochrome) planealloc(PChroma2,w,h);

  planealloc(pmL,mw,mh);
  mLuma.iwidth=mw;
  mLuma.iheight=mh;
  clear(pmL,CONTLUM);

  if(!monochrome)
   { planealloc(pmCh1,mw,mh);
     mChroma1.iwidth=mw;
     mChroma1.iheight=mh;
     clear(pmCh1,CONTCH1);

     planealloc(pmCh2,mw,mh);
     mChroma2.iwidth=mw;
     mChroma2.iheight=mh;
     clear(pmCh2,CONTCH2);
   }


  for(bildnr=0;bildnr<bilder;bildnr++)
   {
    SEEK(offset+imsize*bildnr);
  
    eret=readplain(fin,w,h,PLuma,PChroma1,PChroma2);
    if(eret==E_READ) break;
    error(eret);

    if(!monochrome)
     {interpolate(PChroma1);
      interpolate(PChroma2);
     }

    switch(sbuffer[12+bildnr] & 3)
     {case 0:  imorient=T_NONE; break;
      case 1:  imorient=T_LEFT; break;
      case 3:  imorient=T_RIGHT; break;
      default: imorient=T_NONE;
     }
    pastein(pmL,(bildnr%cols)*xstep,xstep,(bildnr/cols)*ystep,ystep,PLuma,((turn==T_AUTO)? imorient:turn));
    if(!monochrome)
     {pastein(pmCh1,(bildnr%cols)*xstep,xstep,(bildnr/cols)*ystep,ystep,PChroma1,((turn==T_AUTO)? imorient:turn));
      pastein(pmCh2,(bildnr%cols)*xstep,xstep,(bildnr/cols)*ystep,ystep,PChroma2,((turn==T_AUTO)? imorient:turn));
     }
   }

  colconvert(&mw,&mh,pmL,pmCh1,pmCh2);

  if(!ppmname) fout=stdout;
  else
   {if (!(fout=fopen(ppmname,W_OP))) error(E_WRITE);
   }
  writepicture(mw,mh,pmL,pmCh1,pmCh2,CONTORI);

 }








#define ASKIP { argc--; argv ++;}

static void parseargs(argc,argv)
  int argc;
  char **argv;
 {
  char *opt;

  ASKIP;

  while((argc>0) && **argv=='-')
   {
    opt= (*argv)+1;
    ASKIP;

/**** additional options ****/

    if(!strcmp(opt,"x")) 
     { if (!do_overskip) do_overskip=1;
       else error(E_ARG);
       continue;
     }

    if(!strcmp(opt,"s")) 
     { if (!do_sharp) do_sharp=1;
       else error(E_ARG);
       continue;
     }

    if(!strcmp(opt,"d")) 
     { if (!do_diff) do_diff=1;
       else error(E_ARG);
       continue;
     }

    if(!strcmp(opt,"i")) 
     { if (!do_info) do_info=1;
       else error(E_ARG);
       continue;
     }


    if(!strcmp(opt,"m")) 
     { if (!do_melde) do_melde=1;
       else error(E_ARG);
       continue;
     }

    if(!strcmp(opt,"crop")) 
     { if (!do_crop) do_crop=1;
       else error(E_ARG);
       continue;
     }

    if(!strcmp(opt,"pos")) 
     { if (!print_pos) print_pos=1;
       else error(E_ARG);
       continue;
     }

    if(!strcmp(opt,"rep")) 
     { if (!do_rep) do_rep=1;
       else error(E_ARG);
       continue;
     }

/****  Orientation options ****/
 
    if(!strcmp(opt,"n"))
     {if (turn == T_UNSPEC) turn=T_NONE;
      else error(E_ARG);
      continue;
     }

    if(!strcmp(opt,"r"))
     {if (turn == T_UNSPEC) turn=T_RIGHT;
      else error(E_ARG);
      continue;
     }

    if(!strcmp(opt,"l"))
     {if (turn == T_UNSPEC) turn=T_LEFT;
      else error(E_ARG);
      continue;
     }

    if(!strcmp(opt,"a"))
     {if (turn == T_UNSPEC) turn=T_AUTO;
      else error(E_ARG);
      continue;
     }

    if(!strcmp(opt,"vert"))
     {if (!flvert) flvert=1;
      else error(E_ARG);
      continue;
     }

    if(!strcmp(opt,"hori"))
     {if (!flhori) flhori=1;
      else error(E_ARG);
      continue;
     }






/**** Output options ****/


    if((!strcmp(opt,"ppm")) || (!strcmp(opt,"PPM")))
     { if (outfor == O_UNSPEC) outfor=O_PPM;
       else error(E_ARG);
       continue;
     }

    if((!strcmp(opt,"pgm")) || (!strcmp(opt,"PGM")))
     { if (outfor == O_UNSPEC) outfor=O_PGM;
       else error(E_ARG);
       continue;
     }

    if(!strcmp(opt,"ycc")) 
     { if (outfor == O_UNSPEC) outfor=O_YCC;
       else error(E_ARG);
       continue;
     }

    if((!strcmp(opt,"ps")) || (!strcmp(opt,"PS")))
     { if (outfor == O_UNSPEC) outfor=O_PS;
       else error(E_ARG);
       continue;
     }

    if((!strcmp(opt,"eps")) || (!strcmp(opt,"EPS")))
     { if (outfor == O_UNSPEC) outfor=O_EPS;
       else error(E_ARG);
       continue;
     }

    if((!strcmp(opt,"psg")) || (!strcmp(opt,"PSG")))
     { if (outfor == O_UNSPEC) outfor=O_PSG;
       else error(E_ARG);
       continue;
     }

    if((!strcmp(opt,"epsg")) || (!strcmp(opt,"EPSG")))
     { if (outfor == O_UNSPEC) outfor=O_EPSG;
       else error(E_ARG);
       continue;
     }





    if(!strcmp(opt,"pl" ))
     { if(argc<1) error(E_ARG);
       if((sscanf(*argv,"%f",&PAPER_LEFT))!=1) error(E_ARG);
       ASKIP;
       continue;
     }

    if(!strcmp(opt,"pb" ))
     { if(argc<1) error(E_ARG);
       if((sscanf(*argv,"%f",&PAPER_BOTTOM))!=1) error(E_ARG);
       ASKIP;
       continue;
     }


    if(!strcmp(opt,"pw" ))
     { if(argc<1) error(E_ARG);
       if((sscanf(*argv,"%f",&PAPER_WIDTH))!=1) error(E_ARG);
       ASKIP;
       continue;
     }

    if(!strcmp(opt,"ph" ))
     { if(argc<1) error(E_ARG);
       if((sscanf(*argv,"%f",&PAPER_HEIGHT))!=1) error(E_ARG);
       ASKIP;
       continue;
     }

/**** Color model options ****/

    if(!strcmp(opt,"c0")) 
     { if (corrmode == C_UNSPEC) corrmode = C_LINEAR;
       else error(E_ARG);
       continue;
     }

    if(!strcmp(opt,"c-")) 
     { if (corrmode == C_UNSPEC) corrmode = C_DARK;
       else error(E_ARG);
       continue;
     }

    if(!strcmp(opt,"c+")) 
     { if (corrmode == C_UNSPEC) corrmode = C_BRIGHT;
       else error(E_ARG);
       continue;
     }

   



/**** Resolution options ****/
   
    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;
     }

    if((!strcmp(opt,"Contact" )) || (!strcmp(opt,"C")))
     { if (size == S_UNSPEC) size = S_Contact;
       else error(E_ARG);
       if(argc<1) error(E_ARG);
       if((sscanf(*argv,"%d",&contsize))!=1) error(E_ARG);
       ASKIP;
       continue;
     }

   fprintf(stderr,"Unknown option: -%s\n",opt);
   error(E_ARG);
   }

  
  if(argc<1) error(E_ARG);
  pcdname= *argv;
  ASKIP;

  if(argc>0) 
   {ppmname= *argv;
    ASKIP;
   }
  
  if(argc>0) error(E_ARG);


 }
#undef ASKIP










void checkin()
 { 
   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();

 }





These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.