home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / misc / volume39 / hpcdtoppm / part01 / hpcdtoppm.0.5.pl1 / main.c < prev    next >
C/C++ Source or Header  |  1993-08-16  |  24KB  |  1,100 lines

  1. /* hpcdtoppm (Hadmut's pcdtoppm) v0.5pl1
  2. *  Copyright (c) 1992, 1993 by Hadmut Danisch (danisch@ira.uka.de).
  3. *  Permission to use and distribute this software and its
  4. *  documentation for noncommercial use and without fee is hereby granted,
  5. *  provided that the above copyright notice appear in all copies and that
  6. *  both that copyright notice and this permission notice appear in
  7. *  supporting documentation. It is not allowed to sell this software in 
  8. *  any way. This software is not public domain.
  9. */
  10.  
  11. #include "hpcdtoppm.h"
  12.  
  13.  
  14. uBYTE sbuffer[SECSIZE];
  15.  
  16. enum TURNS  turn     = T_UNSPEC;
  17. enum TURNS  contori  = T_UNSPEC;
  18. enum SIZES  size     = S_UNSPEC;
  19. enum OUTFOR outfor   = O_UNSPEC;
  20. enum CORR   corrmode = C_UNSPEC;
  21.  
  22. sINT do_info,do_diff,do_overskip,do_sharp,monochrome,paper;
  23. sINT do_melde,do_rep,do_crop;
  24. sINT flhori=0,flvert=0;
  25. sINT bufpos=0;
  26.  
  27. char *pcdname=0,*ppmname=0;
  28. static FILE  *fin=0,*fout=0;
  29.  
  30. static char    *suba1=0,*suba2=0;
  31. static implane Luma, Chroma1,Chroma2;
  32. static implane *PLuma,*PChroma1,*PChroma2;
  33. static sINT    contsize=1;
  34. static sINT    emulate_seek=0;
  35. static sINT    print_pos;
  36.  
  37.  
  38. #define PrintPos(x) {if(print_pos) fprintf(stderr,"File-Offset: %8d = %8x (hex)\n",(x),(x));}
  39.  
  40. static void checkin(void);
  41. static void parseargs(int,char**);
  42. static void sizecontrol(sizeinfo *,dim,dim);
  43. static void f_1 (dim,dim,sINT,sINT);
  44. static void f_3 (dim,dim,sINT);
  45. static void f_4 (dim,dim,sINT);
  46. static void f_5 (dim,dim);
  47. static void f_ov(dim,dim,sINT,sINT);
  48. static void f_co(dim,dim,sINT,sINT);
  49.  
  50.  
  51.  
  52. void close_all(void)
  53.  {
  54.   if(fin && (fin != stdin)) fclose(fin);
  55.  
  56.   if(fout)
  57.    {if(fout==stdout) 
  58.       fflush(fout);
  59.     else 
  60.       fclose(fout);
  61.    }
  62.  }
  63.  
  64.  
  65.  
  66.  
  67.  
  68.  
  69.  
  70.  
  71. void main(int argc,char **argv)
  72.  {
  73.  
  74.   typecheck();
  75.  
  76.   do_info=do_diff=do_overskip=do_sharp=monochrome=paper=0;
  77.   do_melde=do_rep=do_crop=0;
  78.   print_pos=0;
  79.  
  80.  
  81.   parseargs(argc,argv);
  82.  
  83.   if(size     == S_UNSPEC) size     = S_DEFAULT;
  84.   if(outfor   == O_UNSPEC) outfor   = O_DEFAULT;
  85.   if(corrmode == C_UNSPEC) corrmode = C_DEFAULT;
  86.   if(turn     == T_UNSPEC) turn     = T_DEFAULT;
  87.  
  88.   monochrome=(outfor==O_PGM)||(outfor==O_PSG)||(outfor==O_EPSG)||(outfor==O_PSD)||(outfor==O_EPSD);
  89.   paper     =(outfor==O_PS )||(outfor==O_EPS)||(outfor==O_PSG )||(outfor==O_EPSG)||(outfor==O_PSD)||(outfor==O_EPSD);
  90.  
  91.  
  92.  
  93.   if((size==S_Over) && (!ppmname)) error(E_ARG);
  94.   if((size==S_Contact) && do_crop) error(E_ARG);
  95.   if(do_overskip && do_diff)       error(E_OPT);
  96.  
  97.   if(do_diff && (size != S_4Base) && (size != S_16Base)) error(E_OPT);
  98.  
  99.   if(do_overskip && (size != S_Base16) && (size != S_Base4) && (size != S_Base) && (size != S_4Base) ) error(E_OVSKIP);
  100.   if(print_pos   && (size != S_Base16) && (size != S_Base4) && (size != S_Base) && (size != S_4Base) ) error(E_OPT);
  101.   if(do_info     && (size != S_Base16) && (size != S_Base4) && (size != S_Base) && (size != S_4Base) ) error(E_OPT);
  102.   if(monochrome && do_overskip) error(E_OPT);
  103.   if((size==S_Contact) &&((contsize<1) || (contsize>100))) error(E_OPT);
  104.   if(suba1 && ( size==S_Contact || size==S_Over)) error(E_OPT);
  105.   if(suba1 && do_crop) error(E_OPT);
  106.  
  107.   if((!paper) && (PSIZE_SET || DPI_SET || FAK_SET)) error(E_OPT);
  108.   if(PSIZE_SET && DPI_SET && FAK_SET) error(E_OPT);
  109.   if((DPI_SET || FAK_SET) && (outfor!=O_PSD) && (outfor!=O_EPSD)) error(E_OPT);
  110.  
  111.  
  112.  
  113.  
  114.   if(strcmp(pcdname,"-"))
  115.    { if(!(fin=fopen(pcdname,R_OP))) error(E_READ);
  116.      emulate_seek=0;
  117.    }
  118.   else
  119.    {pcdname="<stdin>";
  120.     emulate_seek=1;
  121. #ifdef USE_FDOPEN
  122.     fin=fdopen(fileno(stdin),R_OP);
  123.     if(!fin) error(E_READ);
  124. #else
  125.     fin=stdin;
  126. #endif
  127.    }
  128.  
  129.   bufpos=0;
  130.  
  131.  
  132.   if((size != S_Over) && (size != S_Contact)) checkin();
  133.  
  134.   PLuma=    &Luma;
  135.   PChroma1= monochrome ? 0 : &Chroma1; 
  136.   PChroma2= monochrome ? 0 : &Chroma2; 
  137.  
  138.   switch(size)
  139.    {
  140.     case S_Base16:  f_1(BaseW/4,BaseH/4,L_Head,(L_Head+L_Base16));
  141.                     break;
  142.  
  143.     case S_Base4:   f_1(BaseW/2,BaseH/2,(L_Head+L_Base16),(L_Head+L_Base16+L_Base4));
  144.                     break;
  145.  
  146.     case S_Base:    f_3(BaseW,BaseH,(L_Head+L_Base16+L_Base4));
  147.                     break;
  148.  
  149.     case S_4Base:   f_4(BaseW*2,BaseH*2,(L_Head+L_Base16+L_Base4));
  150.                     break;
  151.  
  152.     case S_16Base:  f_5(BaseW*4,BaseH*4);
  153.                     break;
  154.  
  155.     case S_Over:    f_ov(BaseW/4,BaseH/4,5,SeBase16);
  156.                     break;
  157.  
  158.     case S_Contact: f_co(BaseW/4,BaseH/4,5,SeBase16);
  159.                     break;
  160.  
  161.     default: error(E_INTERN); 
  162.    }
  163.  
  164.   close_all();
  165.   exit(0);
  166.  
  167.  }
  168.  
  169.  
  170.  
  171.  
  172.  
  173.  
  174. static void openoutput(void)
  175.  {
  176.   if(!ppmname) 
  177.    {
  178. #ifdef USE_FDOPEN
  179.     fout=fdopen(fileno(stdout),W_OP);
  180.     if(!fout) error(E_WRITE);
  181. #else
  182.     fout=stdout;
  183. #endif
  184.    }
  185.   else
  186.    {if (!(fout=fopen(ppmname,W_OP))) error(E_WRITE);
  187.    }
  188.  }
  189.  
  190.  
  191.  
  192.  
  193.  
  194.  
  195.  
  196. static void f_1(dim w,dim h,sINT normal,sINT overskip)
  197.  {sizeinfo si;
  198.  
  199.   sizecontrol(&si,w,h);
  200.  
  201.                    planealloc(PLuma   ,si.rdhlen,si.rdvlen);
  202.   if (!monochrome) planealloc(PChroma1,si.rdhlen,si.rdvlen);
  203.   if (!monochrome) planealloc(PChroma2,si.rdhlen,si.rdvlen);
  204.  
  205.   PrintPos(normal*SECSIZE);
  206.   SEEK(normal+1);                   
  207.       
  208.   if(!do_overskip)
  209.     { error(readplain(&si,1,PLuma,PChroma1,PChroma2));
  210.       if (!monochrome) 
  211.         {interpolate(PChroma1);
  212.          interpolate(PChroma2);
  213.         }
  214.     }
  215.   else
  216.     { error(readplain(&si,1,PLuma,nullplane,nullplane));
  217.       SEEK(overskip+1);
  218.       error(readplain(&si,2,nullplane,PChroma1,PChroma2));
  219.     }
  220.    
  221.  
  222.   colconvert(&si,PLuma,PChroma1,PChroma2);
  223.   /* Now Luma holds red, Chroma1 hold green, Chroma2 holds blue */
  224.  
  225.  
  226.   openoutput();
  227.   writepicture(fout,&si,PLuma,PChroma1,PChroma2,turn);
  228.  
  229.  } 
  230.  
  231.  
  232. static void f_3(dim w,dim h,sINT normal)
  233.  {sINT cd_offset,cd_offhelp;
  234.   sizeinfo si;
  235.  
  236.   sizecontrol(&si,w,h);
  237.  
  238.   PrintPos(normal*SECSIZE);
  239.   SEEK(normal+1);
  240.  
  241.   if(!do_overskip)
  242.     {                 planealloc(PLuma   ,si.rdhlen,si.rdvlen);
  243.      if (!monochrome) planealloc(PChroma1,si.rdhlen,si.rdvlen);
  244.      if (!monochrome) planealloc(PChroma2,si.rdhlen,si.rdvlen);
  245.  
  246.      error(readplain(&si,1,PLuma,PChroma1,PChroma2));
  247.       if (!monochrome) 
  248.         {interpolate(PChroma1);
  249.          interpolate(PChroma2);
  250.         }
  251.     }
  252.    else
  253.     {planealloc(PLuma   ,  si.rdhlen,  si.rdvlen);
  254.      planealloc(PChroma1,2*si.rdhlen,2*si.rdvlen);
  255.      planealloc(PChroma2,2*si.rdhlen,2*si.rdvlen);
  256.  
  257.      error(readplain(&si,1,PLuma,PChroma1,PChroma2));
  258.      interpolate(PChroma1);
  259.      interpolate(PChroma2);
  260.      interpolate(PChroma1);
  261.      interpolate(PChroma2);
  262.  
  263.      cd_offset=Skip4Base();
  264.      SEEK(cd_offset+10);          EREADBUF;    cd_offhelp=(((uINT)sbuffer[2])<<8)|sbuffer[3];
  265.      SEEK(cd_offset+12);          readhqt(3);
  266.      SEEK(cd_offset+cd_offhelp);  decode(&si,4,nullplane,PChroma1,PChroma2,1);
  267.  
  268.      halve(PChroma1);
  269.      halve(PChroma2);
  270.     }
  271.   colconvert(&si,PLuma,PChroma1,PChroma2);
  272.   /* Now Luma holds red, Chroma1 hold green, Chroma2 holds blue */
  273.  
  274.   openoutput();
  275.   writepicture(fout,&si,PLuma,PChroma1,PChroma2,turn);
  276.  
  277.  
  278.  }
  279.  
  280.  
  281.  
  282. static void f_4(dim w,dim h,sINT normal)
  283.  {sINT cd_offset,cd_offhelp;
  284.   sizeinfo si;
  285.   sizecontrol(&si,w,h);
  286.  
  287.                    planealloc(PLuma   ,si.rdhlen,si.rdvlen);
  288.   if (!monochrome) planealloc(PChroma1,si.rdhlen,si.rdvlen);
  289.   if (!monochrome) planealloc(PChroma2,si.rdhlen,si.rdvlen);
  290.  
  291.   PrintPos((L_Head+L_Base16+L_Base4+L_Base)*SECSIZE);
  292.  
  293.   if(!do_overskip)
  294.    {SEEK(L_Head+L_Base16+L_Base4+1);
  295.     error(readplain(&si,-2,PLuma,PChroma1,PChroma2));
  296.     interpolate(PLuma);
  297.     if (!monochrome) 
  298.      {interpolate(PChroma1);
  299.       interpolate(PChroma1);
  300.       interpolate(PChroma2);
  301.       interpolate(PChroma2);
  302.      }
  303.  
  304.     if(do_diff) {clearimpl(PLuma,neutrLum);clearimpl(PChroma1,neutrCh1);clearimpl(PChroma2,neutrCh2);}
  305.  
  306.     cd_offset = L_Head + L_Base16 + L_Base4 + L_Base ;
  307.     SEEK(cd_offset + 4);     readhqt(1);
  308.     SEEK(cd_offset + 5);     decode(&si,1,PLuma,nullplane,nullplane,0);
  309.    }
  310.   else
  311.    {SEEK(L_Head+L_Base16+L_Base4+1);
  312.     error(readplain(&si,-2,PLuma,PChroma1,PChroma2));
  313.     interpolate(PLuma);
  314.     interpolate(PChroma1);
  315.     interpolate(PChroma1);
  316.     interpolate(PChroma2);
  317.     interpolate(PChroma2);
  318.  
  319.     cd_offset = L_Head + L_Base16 + L_Base4 + L_Base ;
  320.     SEEK(cd_offset + 4);     readhqt(1);
  321.     SEEK(cd_offset + 5);     decode(&si,1,PLuma,nullplane,nullplane,0);
  322.  
  323.     cd_offset=bufpos;
  324.     if(cd_offset % SECSIZE) error(E_POS);
  325.     cd_offset/=SECSIZE;
  326.     SEEK(cd_offset+10);          EREADBUF;    cd_offhelp=(((uINT)sbuffer[2])<<8)|sbuffer[3];
  327.     SEEK(cd_offset+12);          readhqt(3);
  328.     SEEK(cd_offset+cd_offhelp);  decode(&si,2,nullplane,PChroma1,PChroma2,1);
  329.      
  330.    }
  331.   colconvert(&si,PLuma,PChroma1,PChroma2);
  332.   /* Now Luma holds red, Chroma1 hold green, Chroma2 holds blue */
  333.  
  334.   openoutput();
  335.   writepicture(fout,&si,PLuma,PChroma1,PChroma2,turn);
  336.  
  337.  }
  338.  
  339.  
  340.  
  341. static void f_5(dim w,dim h)
  342.  {sINT cd_offset;
  343.   sizeinfo si;
  344.  
  345.   sizecontrol(&si,w,h);
  346.  
  347.                    planealloc(PLuma   ,si.rdhlen,si.rdvlen);
  348.   if (!monochrome) planealloc(PChroma1,si.rdhlen,si.rdvlen);
  349.   if (!monochrome) planealloc(PChroma2,si.rdhlen,si.rdvlen);
  350.  
  351.   SEEK(L_Head+L_Base16+L_Base4+1);
  352.   error(readplain(&si,-4,PLuma,PChroma1,PChroma2));
  353.   interpolate(PLuma);
  354.   if(!monochrome)
  355.    {interpolate(PChroma1);
  356.     interpolate(PChroma1);
  357.     interpolate(PChroma2);
  358.     interpolate(PChroma2);
  359.    }
  360.  
  361.   cd_offset = L_Head + L_Base16 + L_Base4 + L_Base ;
  362.   SEEK(cd_offset + 4);       readhqt(1);
  363.   SEEK(cd_offset + 5);       decode(&si,-2,PLuma,nullplane,nullplane,0);
  364.   interpolate(PLuma);
  365.  
  366.   if(do_diff) {clearimpl(PLuma,neutrLum);clearimpl(PChroma1,neutrCh1);clearimpl(PChroma2,neutrCh2);}
  367.  
  368.   cd_offset=bufpos;
  369.   if(cd_offset % SECSIZE) error(E_POS);
  370.   PrintPos(cd_offset);
  371.   cd_offset/=SECSIZE;
  372.  
  373.   SEEK(cd_offset+12);        readhqt(3);
  374.   SEEK(cd_offset+14);        decode(&si,1,PLuma,PChroma1,PChroma2,0);
  375.  
  376.   if(!monochrome)
  377.    {interpolate(PChroma1);
  378.     interpolate(PChroma2);
  379.    }
  380.  
  381.   colconvert(&si,PLuma,PChroma1,PChroma2);
  382.   /* Now Luma holds red, Chroma1 hold green, Chroma2 holds blue */
  383.  
  384.   openoutput();
  385.   writepicture(fout,&si,PLuma,PChroma1,PChroma2,turn);
  386.  
  387.  }
  388.  
  389.  
  390.  
  391.  
  392. static void f_ov(dim w,dim h,sINT offset,sINT imsize)
  393.  {sINT bildnr,bilder;
  394.   dim wx,hx;
  395.   enum ERRORS eret;
  396.   enum TURNS imorient;
  397.   char nbuf[100];
  398.   uBYTE hbuf[SECSIZE];
  399.   sizeinfo si;
  400.   
  401.   sizecontrol(&si,w,h);
  402.  
  403.   wx=w; hx=h;
  404.  
  405.                    planealloc(PLuma   ,si.rdhlen,si.rdvlen);
  406.   if (!monochrome) planealloc(PChroma1,si.rdhlen,si.rdvlen);
  407.   if (!monochrome) planealloc(PChroma2,si.rdhlen,si.rdvlen);
  408.  
  409.  
  410.   SEEK(0); 
  411.   if(READ(hbuf,sizeof(hbuf))<1) error(E_READ);
  412.  
  413.   bilder=(((sINT) hbuf[10])<<8) | hbuf[11];
  414.  
  415.  
  416.   for(bildnr=0;bildnr<bilder;bildnr++)
  417.    {w=wx;h=hx;
  418.     sizecontrol(&si,w,h);
  419.     PLuma->im=PLuma->mp;
  420.     if(PChroma1) PChroma1->im=PChroma1->mp;
  421.     if(PChroma2) PChroma2->im=PChroma2->mp;
  422.  
  423.     SEEK(offset+imsize*bildnr);
  424.   
  425.     eret=readplain(&si,1,PLuma,PChroma1,PChroma2);
  426.     if(eret==E_READ) break;
  427.     error(eret);
  428.  
  429.     if(!monochrome)
  430.      {interpolate(PChroma1);
  431.       interpolate(PChroma2);
  432.      }
  433.  
  434.     colconvert(&si,PLuma,PChroma1,PChroma2);
  435.   
  436.     sprintf(nbuf,"%s%04d",ppmname,bildnr+1);
  437.     if (!(fout=fopen(nbuf,W_OP))) error(E_WRITE);
  438.      switch(hbuf[12+bildnr] & 3)
  439.       {case 0:  imorient=T_NONE;  break;
  440.        case 1:  imorient=T_LEFT;  break;
  441.        case 2:  imorient=T_HEAD;  break;
  442.        case 3:  imorient=T_RIGHT; break;
  443.        default: imorient=T_NONE;
  444.       }
  445.     writepicture(fout,&si,PLuma,PChroma1,PChroma2,turn != T_AUTO ? turn : imorient);
  446.     fclose(fout);
  447.     fout=0;
  448.    }
  449.  }
  450.  
  451.  
  452.  
  453.  
  454. static void f_co(dim w,dim h,sINT offset,sINT imsize)
  455.  {sINT bildnr,bilder,cols,rows,xstep,ystep,mw,mh;
  456.   enum ERRORS eret;
  457.   enum TURNS imorient;
  458.   implane mLuma,mChroma1,mChroma2;
  459.   implane *pmL,*pmCh1,*pmCh2;
  460.   uBYTE hbuf[SECSIZE];
  461.   sizeinfo sibig,sismall;
  462.  
  463.   pmL=                    &mLuma;
  464.   pmCh1= monochrome ? 0 : &mChroma1; 
  465.   pmCh2= monochrome ? 0 : &mChroma2; 
  466.  
  467.  
  468.   SEEK(0); 
  469.   if(READ(hbuf,sizeof(hbuf))<1) error(E_READ);
  470.   bilder=(((sINT) hbuf[10])<<8) | hbuf[11];
  471.  
  472.   cols=contsize;
  473.   rows=(bilder+cols-1)/cols;
  474.  
  475.   xstep=ystep=0;
  476.   switch(turn)
  477.    {case T_NONE: 
  478.     case T_HEAD: xstep=w;ystep=h; break;
  479.     case T_RIGHT:
  480.     case T_LEFT: xstep=h;ystep=w; break;
  481.     case T_AUTO: xstep=ystep=w;   break;
  482.     default: error(E_INTERN);
  483.    }
  484.  
  485.   mw=cols*xstep;
  486.   mh=rows*ystep;
  487.  
  488.   sizecontrol(&sibig  ,mw,mh);
  489.   sizecontrol(&sismall, w, h);
  490.  
  491.   planealloc(PLuma   ,w,h);
  492.   if (!monochrome) planealloc(PChroma1,w,h);
  493.   if (!monochrome) planealloc(PChroma2,w,h);
  494.  
  495.   planealloc(pmL,mw,mh);
  496.   mLuma.iwidth=mw;
  497.   mLuma.iheight=mh;
  498.   clearimpl(pmL,CONTLUM);
  499.  
  500.   if(!monochrome)
  501.    { planealloc(pmCh1,mw,mh);
  502.      mChroma1.iwidth=mw;
  503.      mChroma1.iheight=mh;
  504.      clearimpl(pmCh1,CONTCH1);
  505.  
  506.      planealloc(pmCh2,mw,mh);
  507.      mChroma2.iwidth=mw;
  508.      mChroma2.iheight=mh;
  509.      clearimpl(pmCh2,CONTCH2);
  510.    }
  511.  
  512.  
  513.   for(bildnr=0;bildnr<bilder;bildnr++)
  514.    {SEEK(offset+imsize*bildnr);
  515.   
  516.     eret=readplain(&sismall,1,PLuma,PChroma1,PChroma2);
  517.     if(eret==E_READ) break;
  518.     error(eret);
  519.  
  520.     if(!monochrome)
  521.      {interpolate(PChroma1);
  522.       interpolate(PChroma2);
  523.      }
  524.  
  525.     switch(hbuf[12+bildnr] & 3)
  526.      {case 0:  imorient=T_NONE;  break;
  527.       case 1:  imorient=T_LEFT;  break;
  528.       case 2:  imorient=T_HEAD;  break;
  529.       case 3:  imorient=T_RIGHT; break;
  530.       default: imorient=T_NONE;
  531.      }
  532.     pastein(pmL,(bildnr%cols)*xstep,xstep,(bildnr/cols)*ystep,ystep,PLuma,((turn==T_AUTO)? imorient:turn));
  533.     if(!monochrome)
  534.      {pastein(pmCh1,(bildnr%cols)*xstep,xstep,(bildnr/cols)*ystep,ystep,PChroma1,((turn==T_AUTO)? imorient:turn));
  535.       pastein(pmCh2,(bildnr%cols)*xstep,xstep,(bildnr/cols)*ystep,ystep,PChroma2,((turn==T_AUTO)? imorient:turn));
  536.      }
  537.    }
  538.  
  539.   colconvert(&sibig,pmL,pmCh1,pmCh2);
  540.  
  541.   openoutput();
  542.   writepicture(fout,&sibig,pmL,pmCh1,pmCh2,contori);
  543.  
  544.  }
  545.  
  546.  
  547.  
  548.  
  549.  
  550.  
  551.  
  552.  
  553. #define ASKIP { argc--; argv ++;}
  554.  
  555. static void parseargs(int  argc,char **argv)
  556.  {
  557.   char *opt;
  558.  
  559.   ASKIP;
  560.  
  561.   while((argc>0) && argv[0][0]=='-' && argv[0][1])
  562.    {
  563.     opt= (*argv)+1;
  564.     ASKIP;
  565.  
  566. /**** additional options ****/
  567.  
  568.     if(!strcmp(opt,"x")) 
  569.      { if (!do_overskip) do_overskip=1;
  570.        else error(E_ARG);
  571.        continue;
  572.      }
  573.  
  574.     if(!strcmp(opt,"s")) 
  575.      { if (!do_sharp) do_sharp=1;
  576.        else error(E_ARG);
  577.        continue;
  578.      }
  579.  
  580.     if(!strcmp(opt,"d")) 
  581.      { if (!do_diff) do_diff=1;
  582.        else error(E_ARG);
  583.        continue;
  584.      }
  585.  
  586.     if(!strcmp(opt,"i")) 
  587.      { if (!do_info) do_info=1;
  588.        else error(E_ARG);
  589.        continue;
  590.      }
  591.  
  592.  
  593.     if(!strcmp(opt,"m")) 
  594.      { if (!do_melde) do_melde=1;
  595.        else error(E_ARG);
  596.        continue;
  597.      }
  598.  
  599.     if(!strcmp(opt,"crop")) 
  600.      { if (!do_crop) do_crop=1;
  601.        else error(E_ARG);
  602.        continue;
  603.      }
  604.  
  605.     if(!strcmp(opt,"pos")) 
  606.      { if (!print_pos) print_pos=1;
  607.        else error(E_ARG);
  608.        continue;
  609.      }
  610.  
  611.     if(!strcmp(opt,"rep")) 
  612.      { if (!do_rep) do_rep=1;
  613.        else error(E_ARG);
  614.        continue;
  615.      }
  616.  
  617. /****  Orientation options ****/
  618.  
  619.     if(!strcmp(opt,"n"))
  620.      {if (turn == T_UNSPEC) turn=T_NONE;
  621.       else error(E_ARG);
  622.       continue;
  623.      }
  624.  
  625.     if(!strcmp(opt,"r"))
  626.      {if (turn == T_UNSPEC) turn=T_RIGHT;
  627.       else error(E_ARG);
  628.       continue;
  629.      }
  630.  
  631.     if(!strcmp(opt,"l"))
  632.      {if (turn == T_UNSPEC) turn=T_LEFT;
  633.       else error(E_ARG);
  634.       continue;
  635.      }
  636.  
  637.     if(!strcmp(opt,"h"))
  638.      {if (turn == T_UNSPEC) turn=T_HEAD;
  639.       else error(E_ARG);
  640.       continue;
  641.      }
  642.  
  643.     if(!strcmp(opt,"a"))
  644.      {if (turn == T_UNSPEC) turn=T_AUTO;
  645.       else error(E_ARG);
  646.       continue;
  647.      }
  648.  
  649.     if(!strcmp(opt,"vert"))
  650.      {if (!flvert) flvert=1;
  651.       else error(E_ARG);
  652.       continue;
  653.      }
  654.  
  655.     if(!strcmp(opt,"hori"))
  656.      {if (!flhori) flhori=1;
  657.       else error(E_ARG);
  658.       continue;
  659.      }
  660.  
  661.  
  662.  
  663.  
  664.  
  665.  
  666. /**** Output options ****/
  667.  
  668.  
  669.     if((!strcmp(opt,"ppm")) || (!strcmp(opt,"PPM")))
  670.      { if (outfor == O_UNSPEC) outfor=O_PPM;
  671.        else error(E_ARG);
  672.        continue;
  673.      }
  674.  
  675.     if((!strcmp(opt,"pgm")) || (!strcmp(opt,"PGM")))
  676.      { if (outfor == O_UNSPEC) outfor=O_PGM;
  677.        else error(E_ARG);
  678.        continue;
  679.      }
  680.  
  681.     if(!strcmp(opt,"ycc")) 
  682.      { if (outfor == O_UNSPEC) outfor=O_YCC;
  683.        else error(E_ARG);
  684.        continue;
  685.      }
  686.  
  687.     if((!strcmp(opt,"ps")) || (!strcmp(opt,"PS")))
  688.      { if (outfor == O_UNSPEC) outfor=O_PS;
  689.        else error(E_ARG);
  690.        continue;
  691.      }
  692.  
  693.     if((!strcmp(opt,"eps")) || (!strcmp(opt,"EPS")))
  694.      { if (outfor == O_UNSPEC) outfor=O_EPS;
  695.        else error(E_ARG);
  696.        continue;
  697.      }
  698.  
  699.     if((!strcmp(opt,"psg")) || (!strcmp(opt,"PSG")))
  700.      { if (outfor == O_UNSPEC) outfor=O_PSG;
  701.        else error(E_ARG);
  702.        continue;
  703.      }
  704.  
  705.     if((!strcmp(opt,"epsg")) || (!strcmp(opt,"EPSG")))
  706.      { if (outfor == O_UNSPEC) outfor=O_EPSG;
  707.        else error(E_ARG);
  708.        continue;
  709.      }
  710.  
  711.     if((!strcmp(opt,"psd")) || (!strcmp(opt,"PSD")))
  712.      { if (outfor == O_UNSPEC) outfor=O_PSD;
  713.        else error(E_ARG);
  714.        continue;
  715.      }
  716.  
  717.     if((!strcmp(opt,"epsd")) || (!strcmp(opt,"EPSD")))
  718.      { if (outfor == O_UNSPEC) outfor=O_EPSD;
  719.        else error(E_ARG);
  720.        continue;
  721.      }
  722.  
  723.  
  724.  
  725.  
  726.  
  727.     if(!strcmp(opt,"pl" ))
  728.      { if(argc<1) error(E_ARG);
  729.        if((sscanf(*argv,SSFLTPT,&PAPER_LEFT))!=1) error(E_ARG);
  730.        ASKIP;
  731.        continue;
  732.      }
  733.  
  734.     if(!strcmp(opt,"pb" ))
  735.      { if(argc<1) error(E_ARG);
  736.        if((sscanf(*argv,SSFLTPT,&PAPER_BOTTOM))!=1) error(E_ARG);
  737.        ASKIP;
  738.        continue;
  739.      }
  740.  
  741.  
  742.     if(!strcmp(opt,"pw" ))
  743.      { if(argc<1) error(E_ARG);
  744.        PSIZE_SET=1;
  745.        if((sscanf(*argv,SSFLTPT,&PAPER_WIDTH))!=1) error(E_ARG);
  746.        ASKIP;
  747.        continue;
  748.      }
  749.  
  750.     if(!strcmp(opt,"ph" ))
  751.      { if(argc<1) error(E_ARG);
  752.        PSIZE_SET=1;
  753.        if((sscanf(*argv,SSFLTPT,&PAPER_HEIGHT))!=1) error(E_ARG);
  754.        ASKIP;
  755.        continue;
  756.      }
  757.  
  758.  
  759.     if(!strcmp(opt,"dpi" ))
  760.      { if(argc<1) error(E_ARG);
  761.        DPI_SET=1;
  762.        if((sscanf(*argv,SSFLTPT,&PRINTER_XDPI))!=1) error(E_ARG);
  763.        if(PRINTER_XDPI <= 0.0) error(E_OPT);
  764.        PRINTER_YDPI=PRINTER_XDPI;
  765.        ASKIP;
  766.        continue;
  767.      }
  768.  
  769.     if(!strcmp(opt,"fak" ))
  770.      { if(argc<1) error(E_ARG);
  771.        FAK_SET=1;
  772.        if((sscanf(*argv,SSFLTPT,&PRINTER_FAK))!=1) error(E_ARG);
  773.        if(PRINTER_FAK <= 0.0) error(E_OPT);
  774.        if(PRINTER_FAK >  1000.0) error(E_OPT);
  775.        ASKIP;
  776.        continue;
  777.      }
  778.  
  779.  
  780.  
  781. /**** Color model options ****/
  782.  
  783.     if(!strcmp(opt,"c0")) 
  784.      { if (corrmode == C_UNSPEC) corrmode = C_LINEAR;
  785.        else error(E_ARG);
  786.        continue;
  787.      }
  788.  
  789.     if(!strcmp(opt,"c-")) 
  790.      { if (corrmode == C_UNSPEC) corrmode = C_DARK;
  791.        else error(E_ARG);
  792.        continue;
  793.      }
  794.  
  795.     if(!strcmp(opt,"c+")) 
  796.      { if (corrmode == C_UNSPEC) corrmode = C_BRIGHT;
  797.        else error(E_ARG);
  798.        continue;
  799.      }
  800.  
  801.    
  802. /**** Subrectangel option ****/
  803.     
  804.     if(!strcmp(opt,"S"))
  805.      { if (suba1) error(E_ARG);
  806.        if(argc<2) error(E_ARG);
  807.        suba1=argv[0];
  808.        ASKIP;
  809.        suba2=argv[0];
  810.        ASKIP;
  811.        continue;
  812.      }
  813.  
  814.  
  815. /**** Resolution options ****/
  816.    
  817.     if((!strcmp(opt,"Base/16")) || (!strcmp(opt,"1"))  || (!strcmp(opt,"128x192")))
  818.      { if (size == S_UNSPEC) size = S_Base16;
  819.        else error(E_ARG);
  820.        continue;
  821.      }
  822.     if((!strcmp(opt,"Base/4" )) || (!strcmp(opt,"2"))  || (!strcmp(opt,"256x384")))
  823.      { if (size == S_UNSPEC) size = S_Base4;
  824.        else error(E_ARG);
  825.        continue;
  826.      }
  827.     if((!strcmp(opt,"Base"   )) || (!strcmp(opt,"3"))  || (!strcmp(opt,"512x768")))
  828.      { if (size == S_UNSPEC) size = S_Base;
  829.        else error(E_ARG);
  830.        continue;
  831.      }
  832.     if((!strcmp(opt,"4Base"  )) || (!strcmp(opt,"4"))  || (!strcmp(opt,"1024x1536")))
  833.      { if (size == S_UNSPEC) size = S_4Base;
  834.        else error(E_ARG);
  835.        continue;
  836.      }
  837.     if((!strcmp(opt,"16Base" )) || (!strcmp(opt,"5"))  || (!strcmp(opt,"2048x3072")))
  838.      { if (size == S_UNSPEC) size = S_16Base;
  839.        else error(E_ARG);
  840.        continue;
  841.      }
  842.  
  843.     if((!strcmp(opt,"Overview" )) || (!strcmp(opt,"0"))  || (!strcmp(opt,"O")))
  844.      { if (size == S_UNSPEC) size = S_Over;
  845.        else error(E_ARG);
  846.        continue;
  847.      }
  848.  
  849.     if((!strcmp(opt,"Contact" )) || (!strcmp(opt,"C")))
  850.      { if (size == S_UNSPEC) size = S_Contact;
  851.        else error(E_ARG);
  852.        if(argc<2) error(E_ARG);
  853.        if((sscanf(*argv,"%d",&contsize))!=1) error(E_ARG);
  854.        ASKIP;
  855.        if     (!strcmp(*argv,"n")) contori=T_NONE;
  856.        else if(!strcmp(*argv,"r")) contori=T_RIGHT;
  857.        else if(!strcmp(*argv,"l")) contori=T_LEFT;
  858.        else if(!strcmp(*argv,"h")) contori=T_HEAD;
  859.        else error(E_ARG);
  860.        ASKIP;
  861.  
  862.        continue;
  863.      }
  864.  
  865.    fprintf(stderr,"Unknown option: -%s\n",opt);
  866.    error(E_ARG);
  867.    }
  868.  
  869.   
  870.   if(argc<1) error(E_ARG);
  871.   pcdname= *argv;
  872.   ASKIP;
  873.  
  874.   if(argc>0) 
  875.    {ppmname= *argv;
  876.     ASKIP;
  877.    }
  878.   
  879.   if(argc>0) error(E_ARG);
  880.  
  881.  
  882.  }
  883. #undef ASKIP
  884.  
  885.  
  886.  
  887.  
  888.  
  889.  
  890.  
  891.  
  892.  
  893.  
  894. void checkin(void)
  895.  { 
  896.    if (do_info || (turn==T_AUTO)) 
  897.      { SEEK(1);
  898.        EREADBUF;
  899.      }
  900.  
  901.     if(turn==T_AUTO) 
  902.      {
  903.       switch(sbuffer[0xe02 & 0x7ff]&0x03)
  904.        {case 0x00: turn=T_NONE;  break;
  905.         case 0x01: turn=T_LEFT;  break;
  906.         case 0x02: turn=T_HEAD;  break;
  907.         case 0x03: turn=T_RIGHT; break;
  908.         default: error(E_TCANT);
  909.        }
  910.       }
  911.  
  912.     if(do_info) druckeid();
  913.  
  914.  }
  915.  
  916.  
  917.  
  918. /************************** file access functions **************/
  919.  
  920. int READ(uBYTE *ptr,int n)
  921.  {int d;
  922.   if(!n) return 1;
  923.   bufpos+=n;
  924.   for(;;)
  925.    {d=fread((char *)ptr,1,n,fin);
  926.     if(d<1) return 0;
  927.     n-=d;
  928.     if (!n) break;
  929.     ptr+=d;
  930.    }
  931.   return 1;
  932.  }
  933.  
  934. static int friss(int n)
  935.  {int d;
  936.  
  937.   while(n>0)
  938.    {
  939.     d= n>sizeof(sbuffer) ? sizeof(sbuffer) : n;
  940.     n-=d;
  941.     if(READ(sbuffer,d) !=1) return 1;
  942.    }
  943.  
  944.   return 0;
  945.  }
  946.  
  947.  
  948. void SEEK(int x)
  949.  {
  950.   x *= SECSIZE;
  951.   if(x<bufpos) error(E_INTERN);
  952.   if(x==bufpos) return;
  953.  
  954.   if(emulate_seek)
  955.    {if(friss(x-bufpos)) error(E_READ);
  956.     if(x!=bufpos) error(E_INTERN);
  957.    }
  958.   else
  959.    {bufpos=x;
  960.     if (fseek(fin,x,0)) error(E_READ);
  961.    }
  962. #ifdef DEBUG
  963.   fprintf(stderr,"S-Position %x\n",bufpos);
  964. #endif
  965.  
  966.  }
  967.  
  968.  
  969.  
  970. int SKIPn(int n)
  971.  {
  972.   if(!n) return 0;
  973.   if(n<0) error(E_INTERN);
  974.     
  975.   if(emulate_seek)
  976.    {return friss(n);
  977.    }
  978.   else
  979.    {bufpos+=n;
  980.     return fseek(fin,(n),1);
  981.    }
  982.  }
  983.  
  984.  
  985.  
  986.  
  987.  
  988. /************************** size control functions **************/
  989.  
  990. #define ISDIGIT(x) (((x)>='0') && ((x)<='9'))
  991.  
  992. static void number(char **s,char **i,char **f)
  993.  {char *p;
  994.  
  995.   p= *s;
  996.   (*i)=(*f)=0;
  997.  
  998.   if(!ISDIGIT(*p)) error(E_SUBR);
  999.   while(ISDIGIT(*p)) p++;
  1000.   if(*p != '.') 
  1001.    { *i=*s;
  1002.      *s=p; 
  1003.      return;
  1004.    }
  1005.   p++;
  1006.   if(!ISDIGIT(*p)) error(E_SUBR);
  1007.   while(ISDIGIT(*p)) p++;
  1008.   *f=*s;
  1009.   *s=p;  
  1010.  }
  1011.  
  1012. static sdim makedim(full,i,f)
  1013.   sdim full;
  1014.   char *i,*f;
  1015.  {sdim val;
  1016.   FLTPT fl;
  1017.  
  1018.   if(i) 
  1019.    {if(f) error(E_INTERN);
  1020.     if(sscanf(i,"%u",&val) != 1) error(E_SUBR);
  1021.     if((val<0) || (val >full)) error(E_SUBR);
  1022.     return val;
  1023.    }
  1024.   else
  1025.    {if(!f) error(E_INTERN);
  1026.     if(sscanf(f,SSFLTPT,&fl) != 1) error(E_SUBR);
  1027.     if((fl < 0.0) || (fl > 1.0)) error(E_SUBR);
  1028.     val= full * fl + 0.5;
  1029.     return val;
  1030.    }
  1031.  }
  1032.  
  1033.  
  1034. #define sMASK (~7)
  1035. static void sizealign(char *str,dim full,
  1036.                       dim *rdoff,dim *rdlen,dim *imoff,dim *imlen)
  1037.  {char *i1,*f1,*tr,*i2,*f2,*ptr;
  1038.   int vonbis=0;
  1039.   sdim von,len,rest;
  1040.  
  1041.   i1=f1=tr=i2=f2=0;
  1042.  
  1043.   ptr=str;
  1044.   number(&ptr,&i1,&f1);
  1045.  
  1046.   if(*ptr == '-') vonbis=1;
  1047.   else if (*ptr == '+') vonbis=0;
  1048.   else error(E_SUBR);
  1049.   ptr++;
  1050.  
  1051.   number(&ptr,&i2,&f2);
  1052.   if(*ptr) error(E_SUBR);
  1053.  
  1054.   von=makedim(full,i1,f1);
  1055.   len=makedim(full,i2,f2);
  1056.   if(vonbis) len-=von;
  1057.   rest=full-von-len;
  1058.  
  1059.   if((von<0) || (len<1) || (rest<0)) error(E_SUBR);
  1060.   
  1061.   *imlen = (dim) len;
  1062.  
  1063.   *rdoff = (dim) (von & sMASK); 
  1064.   *rdlen = full - *rdoff - ((dim)( rest & sMASK) );
  1065.  
  1066.   *imoff = ((dim) von) - *rdoff;
  1067.  
  1068.  }
  1069.  
  1070.  
  1071. static void sizecontrol(sizeinfo *si,dim w,dim h)
  1072.  {
  1073.   si->w=w;
  1074.   si->h=h;
  1075.  
  1076.   if(!suba1)
  1077.    {
  1078.     si->rdhlen=w;
  1079.     si->rdvlen=h;
  1080.     si->rdhoff=0;
  1081.     si->rdvoff=0;
  1082.     si->imhlen=0;
  1083.     si->imvlen=0;
  1084.     si->imhoff=0;
  1085.     si->imvoff=0;
  1086.    }
  1087.   else
  1088.    {sizealign(suba1,w,&si->rdhoff,&si->rdhlen,&si->imhoff,&si->imhlen);
  1089.     sizealign(suba2,h,&si->rdvoff,&si->rdvlen,&si->imvoff,&si->imvlen);
  1090.    }
  1091.  
  1092. #ifdef DEBUG
  1093.   fprintf(stderr,"Align: %5d %5d \n",si->w,si->h);
  1094.   fprintf(stderr,"Align: %5d %5d %5d %5d \n",si->rdhoff,si->rdhlen,si->rdvoff,si->rdvlen);
  1095.   fprintf(stderr,"Align: %5d %5d %5d %5d \n",si->imhoff,si->imhlen,si->imvoff,si->imvlen);
  1096. #endif
  1097.  
  1098.  }
  1099.  
  1100.