home *** CD-ROM | disk | FTP | other *** search
/ AMIGA PD 1 / AMIGA-PD-1.iso / Programme_zum_Heft / Anwendungen / Kurztests / PBM / HPCDTOPPM_0_6.LHA / hpcdtoppm.0.6 / src / main.c < prev    next >
C/C++ Source or Header  |  1994-10-08  |  30KB  |  1,366 lines

  1. /* hpcdtoppm (Hadmut's pcdtoppm) v0.6
  2. *  Copyright (c) 1992, 1993, 1994 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; /* ,*dir64=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. static char    dir64[512];
  38. static void    get_dir64(void);
  39.  
  40. #define PrintPos(x) {if(print_pos) fprintf(stderr,"File-Offset: %8d = %8x (hex) = %d (sec)\n",(x),(x),(x)/0x800);}
  41.  
  42. static void checkin(void);
  43. static void parseargs(int,char**);
  44. static void sizecontrol(sizeinfo *,dim,dim,dim sMASK);
  45. static void f_1 (dim,dim,sINT,sINT);
  46. static void f_3 (dim,dim,sINT);
  47. static void f_4 (dim,dim,sINT);
  48. static void f_5 (dim,dim);
  49. static void f_6 (dim,dim);
  50. static void f_ov(dim,dim,sINT,sINT);
  51. static void f_co(dim,dim,sINT,sINT);
  52.  
  53.  
  54.  
  55. void close_all(void)
  56.  {
  57.   if(fin && (fin != stdin)) fclose(fin);
  58.  
  59.   if(fout)
  60.    {if(fout==stdout) 
  61.       fflush(fout);
  62.     else 
  63.       fclose(fout);
  64.    }
  65.  }
  66.  
  67.  
  68.  
  69.  
  70.  
  71.  
  72.  
  73.  
  74. void main(int argc,char **argv)
  75.  {
  76.  
  77.   typecheck();
  78.  
  79.   do_info=do_diff=do_overskip=do_sharp=monochrome=paper=0;
  80.   do_melde=do_rep=do_crop=0;
  81.   print_pos=0;
  82.  
  83.  
  84.   parseargs(argc,argv);
  85.  
  86.   if(size     == S_UNSPEC) size     = S_DEFAULT;
  87.   if(outfor   == O_UNSPEC) outfor   = O_DEFAULT;
  88.   if(corrmode == C_UNSPEC) corrmode = C_DEFAULT;
  89.   if(turn     == T_UNSPEC) turn     = T_DEFAULT;
  90.  
  91.   monochrome=(outfor==O_PGM)||(outfor==O_PSG)||(outfor==O_EPSG)||(outfor==O_PSD)||(outfor==O_EPSD);
  92.   paper     =(outfor==O_PS )||(outfor==O_EPS)||(outfor==O_PSG )||(outfor==O_EPSG)||(outfor==O_PSD)||(outfor==O_EPSD);
  93.  
  94.  
  95.  
  96.   if((size==S_Over) && (!ppmname)) error(E_ARG);
  97.   if((size==S_Contact) && do_crop) error(E_ARG);
  98.   if(do_overskip && do_diff)       error(E_OPT);
  99.  
  100.   if(do_diff && (size != S_4Base) && (size != S_16Base) && (size != S_64Base)) error(E_OPT);
  101.  
  102.   if(do_overskip && (size != S_Base16) && (size != S_Base4) && (size != S_Base) && (size != S_4Base) ) error(E_OVSKIP);
  103.   if(print_pos   && (size != S_Base16) && (size != S_Base4) && (size != S_Base) && (size != S_4Base) ) error(E_OPT);
  104.   if(do_info     && (size != S_Base16) && (size != S_Base4) && (size != S_Base) && (size != S_4Base) ) error(E_OPT);
  105.   if(monochrome && do_overskip) error(E_OPT);
  106.   if((size==S_Contact) &&((contsize<1) || (contsize>100))) error(E_OPT);
  107.   if(suba1 && ( size==S_Contact || size==S_Over)) error(E_OPT);
  108.   if(suba1 && do_crop) error(E_OPT);
  109.  
  110.   if((!paper) && (PSIZE_SET || DPI_SET || FAK_SET)) error(E_OPT);
  111.   if(PSIZE_SET && DPI_SET && FAK_SET) error(E_OPT);
  112.   if((DPI_SET || FAK_SET) && (outfor!=O_PSD) && (outfor!=O_EPSD)) error(E_OPT);
  113.  
  114.  
  115.  
  116.  
  117.   if(strcmp(pcdname,"-"))
  118.    { if(!(fin=fopen(pcdname,R_OP))) error(E_FOPEN);
  119.      emulate_seek=0;
  120.    }
  121.   else
  122.    {pcdname="<stdin>";
  123.     emulate_seek=1;
  124.     /* 64Base can't be on stdin - need a suitable error message */
  125.     if (size == S_64Base) error(E_FOPEN);
  126. #ifdef USE_FDOPEN
  127.     fin=fdopen(fileno(stdin),R_OP);
  128.     if(!fin) error(E_READ);
  129. #else
  130.     fin=stdin;
  131. #endif
  132.    }
  133.  
  134.   bufpos=0;
  135.  
  136.  
  137.   if((size != S_Over) && (size != S_Contact)) checkin();
  138.  
  139.   PLuma=    &Luma;
  140.   PChroma1= monochrome ? 0 : &Chroma1; 
  141.   PChroma2= monochrome ? 0 : &Chroma2; 
  142.  
  143.   switch(size)
  144.    {
  145.     case S_Base16:  f_1(BaseW/4,BaseH/4,L_Head,(L_Head+L_Base16));
  146.                     break;
  147.  
  148.     case S_Base4:   f_1(BaseW/2,BaseH/2,(L_Head+L_Base16),(L_Head+L_Base16+L_Base4));
  149.                     break;
  150.  
  151.     case S_Base:    f_3(BaseW,BaseH,(L_Head+L_Base16+L_Base4));
  152.                     break;
  153.  
  154.     case S_4Base:   f_4(BaseW*2,BaseH*2,(L_Head+L_Base16+L_Base4));
  155.                     break;
  156.  
  157.     case S_16Base:  f_5(BaseW*4,BaseH*4);
  158.                     break;
  159.  
  160.     case S_64Base:  f_6(BaseW*8,BaseH*8);
  161.                     break;
  162.  
  163.     case S_Over:    f_ov(BaseW/4,BaseH/4,5,SeBase16);
  164.                     break;
  165.  
  166.     case S_Contact: f_co(BaseW/4,BaseH/4,5,SeBase16);
  167.                     break;
  168.  
  169.     default: error(E_INTERN); 
  170.    }
  171.  
  172.   close_all();
  173.   exit(0);
  174.  
  175.  }
  176.  
  177.  
  178.  
  179.  
  180.  
  181.  
  182. static void openoutput(void)
  183.  {
  184.   if(!ppmname) 
  185.    {
  186. #ifdef USE_FDOPEN
  187.     fout=fdopen(fileno(stdout),W_OP);
  188.     if(!fout) error(E_WRITE);
  189. #else
  190.     fout=stdout;
  191. #endif
  192.    }
  193.   else
  194.    {if (!(fout=fopen(ppmname,W_OP))) error(E_WRITE);
  195.    }
  196.  }
  197.  
  198.  
  199.  
  200.  
  201.  
  202.  
  203.  
  204. static void f_1(dim w,dim h,sINT normal,sINT overskip)
  205.  {sizeinfo si;
  206.  
  207.   sizecontrol(&si,w,h,~3);
  208.  
  209.                    planealloc(PLuma   ,si.rdhlen,si.rdvlen);
  210.   if (!monochrome) planealloc(PChroma1,si.rdhlen,si.rdvlen);
  211.   if (!monochrome) planealloc(PChroma2,si.rdhlen,si.rdvlen);
  212.  
  213.   PrintPos(normal*SECSIZE);
  214.   SEEK(normal+1);                   
  215.       
  216.   if(!do_overskip)
  217.     { error(readplain(&si,1,PLuma,PChroma1,PChroma2));
  218.       if (!monochrome) 
  219.         {interpolate(PChroma1);
  220.          interpolate(PChroma2);
  221.         }
  222.     }
  223.   else
  224.     { error(readplain(&si,1,PLuma,nullplane,nullplane));
  225.       SEEK(overskip+1);
  226.       error(readplain(&si,2,nullplane,PChroma1,PChroma2));
  227.     }
  228.    
  229.  
  230.   colconvert(&si,PLuma,PChroma1,PChroma2);
  231.   /* Now Luma holds red, Chroma1 hold green, Chroma2 holds blue */
  232.  
  233.  
  234.   openoutput();
  235.   writepicture(fout,&si,PLuma,PChroma1,PChroma2,turn);
  236.  
  237.  } 
  238.  
  239.  
  240. static void f_3(dim w,dim h,sINT normal)
  241.  {sINT cd_offset,cd_offhelp;
  242.   sizeinfo si;
  243.  
  244.   sizecontrol(&si,w,h,~3);
  245.  
  246.   PrintPos(normal*SECSIZE);
  247.   SEEK(normal+1);
  248.  
  249.   if(!do_overskip)
  250.     {                 planealloc(PLuma   ,si.rdhlen,si.rdvlen);
  251.      if (!monochrome) planealloc(PChroma1,si.rdhlen,si.rdvlen);
  252.      if (!monochrome) planealloc(PChroma2,si.rdhlen,si.rdvlen);
  253.  
  254.      error(readplain(&si,1,PLuma,PChroma1,PChroma2));
  255.       if (!monochrome) 
  256.         {interpolate(PChroma1);
  257.          interpolate(PChroma2);
  258.         }
  259.     }
  260.    else
  261.     {planealloc(PLuma   ,  si.rdhlen,  si.rdvlen);
  262.      planealloc(PChroma1,2*si.rdhlen,2*si.rdvlen);
  263.      planealloc(PChroma2,2*si.rdhlen,2*si.rdvlen);
  264.  
  265.      error(readplain(&si,1,PLuma,PChroma1,PChroma2));
  266.      interpolate(PChroma1);
  267.      interpolate(PChroma2);
  268.      interpolate(PChroma1);
  269.      interpolate(PChroma2);
  270.  
  271.      cd_offset=Skip4Base();
  272.      SEEK(cd_offset+10);          EREADBUF;    cd_offhelp=(((uINT)sbuffer[2])<<8)|sbuffer[3];
  273.      SEEK(cd_offset+12);          readhqt(3);
  274.      SEEK(cd_offset+cd_offhelp);  decode(&si,4,nullplane,PChroma1,PChroma2,1);
  275.  
  276.      halve(PChroma1);
  277.      halve(PChroma2);
  278.     }
  279.   colconvert(&si,PLuma,PChroma1,PChroma2);
  280.   /* Now Luma holds red, Chroma1 hold green, Chroma2 holds blue */
  281.  
  282.   openoutput();
  283.   writepicture(fout,&si,PLuma,PChroma1,PChroma2,turn);
  284.  
  285.  
  286.  }
  287.  
  288.  
  289.  
  290. static void f_4(dim w,dim h,sINT normal)
  291.  {sINT cd_offset,cd_offhelp;
  292.   sizeinfo si;
  293.   sizecontrol(&si,w,h,~3);
  294.  
  295.                    planealloc(PLuma   ,si.rdhlen,si.rdvlen);
  296.   if (!monochrome) planealloc(PChroma1,si.rdhlen,si.rdvlen);
  297.   if (!monochrome) planealloc(PChroma2,si.rdhlen,si.rdvlen);
  298.  
  299.   PrintPos((L_Head+L_Base16+L_Base4+L_Base)*SECSIZE);
  300.  
  301.   if(!do_overskip)
  302.    {SEEK(L_Head+L_Base16+L_Base4+1);
  303.     error(readplain(&si,-2,PLuma,PChroma1,PChroma2));
  304.     interpolate(PLuma);
  305.     if (!monochrome) 
  306.      {interpolate(PChroma1);
  307.       interpolate(PChroma1);
  308.       interpolate(PChroma2);
  309.       interpolate(PChroma2);
  310.      }
  311.  
  312.     if(do_diff) {clearimpl(PLuma,neutrLum);clearimpl(PChroma1,neutrCh1);clearimpl(PChroma2,neutrCh2);}
  313.  
  314.     cd_offset = L_Head + L_Base16 + L_Base4 + L_Base ;
  315.     SEEK(cd_offset + 4);     readhqt(1);
  316.     SEEK(cd_offset + 5);     decode(&si,1,PLuma,nullplane,nullplane,0);
  317.    }
  318.   else
  319.    {SEEK(L_Head+L_Base16+L_Base4+1);
  320.     error(readplain(&si,-2,PLuma,PChroma1,PChroma2));
  321.     interpolate(PLuma);
  322.     interpolate(PChroma1);
  323.     interpolate(PChroma1);
  324.     interpolate(PChroma2);
  325.     interpolate(PChroma2);
  326.  
  327.     cd_offset = L_Head + L_Base16 + L_Base4 + L_Base ;
  328.     SEEK(cd_offset + 4);     readhqt(1);
  329.     SEEK(cd_offset + 5);     decode(&si,1,PLuma,nullplane,nullplane,0);
  330.  
  331.     cd_offset=bufpos;
  332.     if(cd_offset % SECSIZE) error(E_POS);
  333.     cd_offset/=SECSIZE;
  334.     SEEK(cd_offset+10);          EREADBUF;    cd_offhelp=(((uINT)sbuffer[2])<<8)|sbuffer[3];
  335.     SEEK(cd_offset+12);          readhqt(3);
  336.     SEEK(cd_offset+cd_offhelp);  decode(&si,2,nullplane,PChroma1,PChroma2,1);
  337.      
  338.    }
  339.   colconvert(&si,PLuma,PChroma1,PChroma2);
  340.   /* Now Luma holds red, Chroma1 hold green, Chroma2 holds blue */
  341.  
  342.   openoutput();
  343.   writepicture(fout,&si,PLuma,PChroma1,PChroma2,turn);
  344.  
  345.  }
  346.  
  347.  
  348.  
  349.  
  350.  
  351.  
  352.  
  353.  
  354.  
  355.  
  356.  
  357.  
  358.  
  359. static void f_5sub(dim w, dim h, sizeinfo *sip,int fak1,int fak2,int fak3,dim sMASK)
  360.  {sINT cd_offset;
  361.   
  362.   sizecontrol(sip,w,h,sMASK);
  363.  
  364.                    planealloc(PLuma   ,sip->rdhlen,sip->rdvlen);
  365.   if (!monochrome) planealloc(PChroma1,sip->rdhlen,sip->rdvlen);
  366.   if (!monochrome) planealloc(PChroma2,sip->rdhlen,sip->rdvlen);
  367.  
  368.   SEEK(L_Head+L_Base16+L_Base4+1);
  369.   error(readplain(sip,fak1,PLuma,PChroma1,PChroma2));
  370.   interpolate(PLuma);
  371.   if(!monochrome)
  372.    {interpolate(PChroma1);
  373.     interpolate(PChroma1);
  374.     interpolate(PChroma2);
  375.     interpolate(PChroma2);
  376.    }
  377.  
  378.   cd_offset = L_Head + L_Base16 + L_Base4 + L_Base ;
  379.   SEEK(cd_offset + 4);       readhqt(1);
  380.   SEEK(cd_offset + 5);       decode(sip,fak2,PLuma,nullplane,nullplane,0);
  381.   interpolate(PLuma);
  382.  
  383.   if(do_diff) {clearimpl(PLuma,neutrLum);clearimpl(PChroma1,neutrCh1);clearimpl(PChroma2,neutrCh2);}
  384.  
  385.   cd_offset=bufpos;
  386.   if(cd_offset % SECSIZE) error(E_POS);
  387.   PrintPos(cd_offset);
  388.   cd_offset/=SECSIZE;
  389.  
  390.   SEEK(cd_offset+12);        readhqt(3);
  391.   SEEK(cd_offset+14);        decode(sip,fak3,PLuma,PChroma1,PChroma2,0);
  392.  
  393.  }
  394.  
  395.  
  396.  
  397.  
  398. static void f_5(dim w,dim h)
  399.  {sizeinfo si;
  400.  
  401.   f_5sub(w,h,&si,-4,-2,1,~7);
  402.  
  403.   if(!monochrome)
  404.    {interpolate(PChroma1);
  405.     interpolate(PChroma2);
  406.    }
  407.  
  408.   colconvert(&si,PLuma,PChroma1,PChroma2);
  409.   /* Now Luma holds red, Chroma1 hold green, Chroma2 holds blue */
  410.  
  411.   openoutput();
  412.   writepicture(fout,&si,PLuma,PChroma1,PChroma2,turn);
  413.  
  414.  }
  415.  
  416.  
  417.  
  418.  
  419. static void f_6(dim w,dim h)
  420.  {sizeinfo si;
  421.   FILE *ic,*icr[10];
  422.   struct ic_header ic_h;
  423.   struct ic_descr descr[3];
  424.   struct ic_fname names[10];
  425.   struct ic_entry efrom,eto;
  426.   struct file16 namecount,descrcount;
  427.   int i,j,nc,dc;
  428.   char   FN[300];
  429.   int first,last,ffrom,fto,foff;
  430.  
  431.  
  432.   f_5sub(w,h,&si,-8,-4,-2,~15);
  433.  
  434.   interpolate(PLuma);
  435.   if(!monochrome)
  436.    {interpolate(PChroma1);
  437.     interpolate(PChroma2);
  438.    }
  439.  
  440.   get_dir64();
  441.  
  442.   sprintf(FN,"%s%c%s",dir64,DIRSEP,"info.ic");
  443.   if(!(ic=fopen(FN,R_OP))) error(E_FOPEN);
  444.   if(fread(&ic_h,sizeof(ic_h),1,ic)<1) error(E_READ);
  445.  
  446.  
  447.  
  448.  
  449.   /******************************************************************************/
  450.   /* layer descriptions */
  451.   /******************************************************************************/
  452.   if(fseek(ic,FILE32(ic_h.off_descr),0)) error(E_READ);
  453.   
  454.   if(fread(&descrcount,sizeof(descrcount),1,ic)<1) error(E_READ);
  455.   dc=FILE16(descrcount);
  456.  
  457.   if((dc<1) || (dc>3)) error(E_SEQ);
  458.   if((!monochrome) && (dc<3))         error(E_SEQ);
  459.  
  460.   if(fread(descr,sizeof(descr[0]),dc,ic)<dc) error(E_READ);
  461.  
  462.  
  463.  
  464.  
  465.  
  466.  
  467.   /******************************************************************************/
  468.   /* Filenames */
  469.   /******************************************************************************/
  470.   if(fseek(ic,FILE32(ic_h.off_fnames),0)) error(E_READ);
  471.  
  472.   if(fread(&namecount,sizeof(namecount),1,ic)<1) error(E_READ);
  473.   nc=FILE16(namecount);
  474.  
  475.   if((nc<1) || (nc>10)) error(E_SEQ);
  476.   if((!monochrome) && (nc<3))         error(E_SEQ);
  477.  
  478.   if(fread(names,sizeof(names[0]),nc,ic)<nc) error(E_READ);
  479.  
  480. #ifdef SMALLNAMES
  481.   for (i=0;i<nc;i++)
  482.    { 
  483.     {for (j=0;j<sizeof(names[0].fname);j++)
  484.       {if((names[i].fname[j]>= 'A') && (names[i].fname[j]<= 'Z'))
  485.         names[i].fname[j] += 'a'-'A';
  486.       }
  487.     }
  488. #ifdef DEBUG
  489.    fprintf(stderr,"%-*.*s %d\n",sizeof(names[0].fname),sizeof(names[0].fname),names[i].fname, FILE32(names[i].size));
  490. #endif
  491. #endif
  492.    }
  493.  
  494.  
  495.   /******************************************************************************/
  496.   /* Huffman-Tables */
  497.   /******************************************************************************/
  498.   if(fseek(ic,FILE32(ic_h.off_huffman),0)) error(E_READ);
  499.   if(fread(sbuffer,1,sizeof(sbuffer),ic)<5) error(E_READ);
  500.  
  501.   readhqtx(monochrome?1:3);
  502.  
  503.  
  504.  
  505.   /******************************************************************************/
  506.   /* Decode it */
  507.   /******************************************************************************/
  508.   for(i=0;i< (monochrome?1:3); i++)
  509.    {
  510.     first=si.rdvoff;    last =si.rdvoff+si.rdvlen;
  511.  
  512.     if(!i)
  513.      { /* luma */
  514.        if(last>=h) last=h-1;
  515.      }
  516.     else
  517.      { /* chroma */
  518.        first/=2;
  519.        last=(last+1)/2;
  520.        if(last>=h/2) last=h/2-1;
  521.      }
  522.  
  523.     if(fseek(ic,FILE32(descr[i].off_pointers)+ 6*4*first,0)) error(E_READ);
  524.     if(fread(&efrom,sizeof(efrom),1,ic)<1) error(E_READ);
  525.  
  526.     if(fseek(ic,FILE32(descr[i].off_pointers)+ 6*4*last,0)) error(E_READ);
  527.     if(fread(&eto  ,sizeof(eto  ),1,ic)<1) error(E_READ);
  528.  
  529.     ffrom=FILE16(efrom.fno);
  530.     fto  =FILE16(eto.fno);
  531.     foff =FILE32(efrom.offset);
  532.  
  533.  
  534. /*    fprintf(stderr,"XXX:  %d  %d  %d\n",ffrom,fto,foff);*/
  535.  
  536.     for(j=ffrom;j<=fto;j++)
  537.      {sprintf(FN,"%s%c%s",dir64,DIRSEP,names[j].fname);
  538.  
  539. #ifdef DEBUG
  540.     fprintf(stderr,"Filename %s\n",FN);
  541. #endif
  542.       if(!(icr[j-ffrom]=fopen(FN,R_OP))) error(E_FOPEN);
  543.      }
  544.     icr[j-ffrom]=0;
  545.  
  546.     if(fseek(icr[0],foff,0)) error(E_READ);
  547.  
  548.     switch (i)
  549.      {case 0:  decodex(icr,0,&descr[0],&si, 1,PLuma,   1);  break;
  550.       case 1:  decodex(icr,1,&descr[1],&si,-2,PChroma1,1);  break;
  551.       case 2:  decodex(icr,2,&descr[2],&si,-2,PChroma2,1);  break;
  552.      }
  553.  
  554.  
  555.     for(j=ffrom;j<=fto;j++)  fclose(icr[j-ffrom]);
  556.  
  557.  
  558.    }
  559.   fclose(ic);
  560.  
  561.   if(!monochrome)
  562.    {interpolate(PChroma1);
  563.     interpolate(PChroma2);
  564.    }
  565.  
  566.   colconvert(&si,PLuma,PChroma1,PChroma2);
  567.   openoutput();
  568.   writepicture(fout,&si,PLuma,PChroma1,PChroma2,turn);
  569.  
  570.  }
  571.  
  572.  
  573.  
  574.  
  575.  
  576.  
  577.  
  578.  
  579.  
  580.  
  581.  
  582.  
  583.  
  584.  
  585.  
  586.  
  587. static void f_ov(dim w,dim h,sINT offset,sINT imsize)
  588.  {sINT bildnr,bilder;
  589.   dim wx,hx;
  590.   enum ERRORS eret;
  591.   enum TURNS imorient;
  592.   char nbuf[100];
  593.   uBYTE hbuf[SECSIZE];
  594.   sizeinfo si;
  595.   
  596.   sizecontrol(&si,w,h,~3);
  597.  
  598.   wx=w; hx=h;
  599.  
  600.                    planealloc(PLuma   ,si.rdhlen,si.rdvlen);
  601.   if (!monochrome) planealloc(PChroma1,si.rdhlen,si.rdvlen);
  602.   if (!monochrome) planealloc(PChroma2,si.rdhlen,si.rdvlen);
  603.  
  604.  
  605.   SEEK(0); 
  606.   if(READ(hbuf,sizeof(hbuf))<1) error(E_READ);
  607.  
  608.   bilder=(((sINT) hbuf[10])<<8) | hbuf[11];
  609.  
  610.  
  611.   for(bildnr=0;bildnr<bilder;bildnr++)
  612.    {w=wx;h=hx;
  613.     sizecontrol(&si,w,h,~3);
  614.     PLuma->im=PLuma->mp;
  615.     if(PChroma1) PChroma1->im=PChroma1->mp;
  616.     if(PChroma2) PChroma2->im=PChroma2->mp;
  617.  
  618.     SEEK(offset+imsize*bildnr);
  619.   
  620.     eret=readplain(&si,1,PLuma,PChroma1,PChroma2);
  621.     if(eret==E_READ) break;
  622.     error(eret);
  623.  
  624.     if(!monochrome)
  625.      {interpolate(PChroma1);
  626.       interpolate(PChroma2);
  627.      }
  628.  
  629.     colconvert(&si,PLuma,PChroma1,PChroma2);
  630.   
  631.     sprintf(nbuf,"%s%04d",ppmname,bildnr+1);
  632.     if (!(fout=fopen(nbuf,W_OP))) error(E_WRITE);
  633.      switch(hbuf[12+bildnr] & 3)
  634.       {case 0:  imorient=T_NONE;  break;
  635.        case 1:  imorient=T_LEFT;  break;
  636.        case 2:  imorient=T_HEAD;  break;
  637.        case 3:  imorient=T_RIGHT; break;
  638.        default: imorient=T_NONE;
  639.       }
  640.     writepicture(fout,&si,PLuma,PChroma1,PChroma2,turn != T_AUTO ? turn : imorient);
  641.     fclose(fout);
  642.     fout=0;
  643.    }
  644.  }
  645.  
  646.  
  647.  
  648.  
  649. static void f_co(dim w,dim h,sINT offset,sINT imsize)
  650.  {sINT bildnr,bilder,cols,rows,xstep,ystep,mw,mh;
  651.   enum ERRORS eret;
  652.   enum TURNS imorient;
  653.   implane mLuma,mChroma1,mChroma2;
  654.   implane *pmL,*pmCh1,*pmCh2;
  655.   uBYTE hbuf[SECSIZE];
  656.   sizeinfo sibig,sismall;
  657.  
  658.   pmL=                    &mLuma;
  659.   pmCh1= monochrome ? 0 : &mChroma1; 
  660.   pmCh2= monochrome ? 0 : &mChroma2; 
  661.  
  662.  
  663.   SEEK(0); 
  664.   if(READ(hbuf,sizeof(hbuf))<1) error(E_READ);
  665.   bilder=(((sINT) hbuf[10])<<8) | hbuf[11];
  666.  
  667.   cols=contsize;
  668.   rows=(bilder+cols-1)/cols;
  669.  
  670.   xstep=ystep=0;
  671.   switch(turn)
  672.    {case T_NONE: 
  673.     case T_HEAD: xstep=w;ystep=h; break;
  674.     case T_RIGHT:
  675.     case T_LEFT: xstep=h;ystep=w; break;
  676.     case T_AUTO: xstep=ystep=w;   break;
  677.     default: error(E_INTERN);
  678.    }
  679.  
  680.   mw=cols*xstep;
  681.   mh=rows*ystep;
  682.  
  683.   sizecontrol(&sibig  ,mw,mh,~3);
  684.   sizecontrol(&sismall, w, h,~3);
  685.  
  686.   planealloc(PLuma   ,w,h);
  687.   if (!monochrome) planealloc(PChroma1,w,h);
  688.   if (!monochrome) planealloc(PChroma2,w,h);
  689.  
  690.   planealloc(pmL,mw,mh);
  691.   mLuma.iwidth=mw;
  692.   mLuma.iheight=mh;
  693.   clearimpl(pmL,CONTLUM);
  694.  
  695.   if(!monochrome)
  696.    { planealloc(pmCh1,mw,mh);
  697.      mChroma1.iwidth=mw;
  698.      mChroma1.iheight=mh;
  699.      clearimpl(pmCh1,CONTCH1);
  700.  
  701.      planealloc(pmCh2,mw,mh);
  702.      mChroma2.iwidth=mw;
  703.      mChroma2.iheight=mh;
  704.      clearimpl(pmCh2,CONTCH2);
  705.    }
  706.  
  707.  
  708.   for(bildnr=0;bildnr<bilder;bildnr++)
  709.    {SEEK(offset+imsize*bildnr);
  710.   
  711.     eret=readplain(&sismall,1,PLuma,PChroma1,PChroma2);
  712.     if(eret==E_READ) break;
  713.     error(eret);
  714.  
  715.     if(!monochrome)
  716.      {interpolate(PChroma1);
  717.       interpolate(PChroma2);
  718.      }
  719.  
  720.     switch(hbuf[12+bildnr] & 3)
  721.      {case 0:  imorient=T_NONE;  break;
  722.       case 1:  imorient=T_LEFT;  break;
  723.       case 2:  imorient=T_HEAD;  break;
  724.       case 3:  imorient=T_RIGHT; break;
  725.       default: imorient=T_NONE;
  726.      }
  727.     pastein(pmL,(bildnr%cols)*xstep,xstep,(bildnr/cols)*ystep,ystep,PLuma,((turn==T_AUTO)? imorient:turn));
  728.     if(!monochrome)
  729.      {pastein(pmCh1,(bildnr%cols)*xstep,xstep,(bildnr/cols)*ystep,ystep,PChroma1,((turn==T_AUTO)? imorient:turn));
  730.       pastein(pmCh2,(bildnr%cols)*xstep,xstep,(bildnr/cols)*ystep,ystep,PChroma2,((turn==T_AUTO)? imorient:turn));
  731.      }
  732.    }
  733.  
  734.   colconvert(&sibig,pmL,pmCh1,pmCh2);
  735.  
  736.   openoutput();
  737.   writepicture(fout,&sibig,pmL,pmCh1,pmCh2,contori);
  738.  
  739.  }
  740.  
  741.  
  742.  
  743.  
  744.  
  745.  
  746.  
  747.  
  748. #define ASKIP { argc--; argv ++;}
  749.  
  750. static void parseargs(int  argc,char **argv)
  751.  {
  752.   char *opt;
  753.  
  754.   ASKIP;
  755.  
  756.   while((argc>0) && argv[0][0]=='-' && argv[0][1])
  757.    {
  758.     opt= (*argv)+1;
  759.     ASKIP;
  760.  
  761. /**** additional options ****/
  762.  
  763.     if(!strcmp(opt,"x")) 
  764.      { if (!do_overskip) do_overskip=1;
  765.        else error(E_ARG);
  766.        continue;
  767.      }
  768.  
  769.     if(!strcmp(opt,"s")) 
  770.      { if (!do_sharp) do_sharp=1;
  771.        else error(E_ARG);
  772.        continue;
  773.      }
  774.  
  775.     if(!strcmp(opt,"d")) 
  776.      { if (!do_diff) do_diff=1;
  777.        else error(E_ARG);
  778.        continue;
  779.      }
  780.  
  781.     if(!strcmp(opt,"i")) 
  782.      { if (!do_info) do_info=1;
  783.        else error(E_ARG);
  784.        continue;
  785.      }
  786.  
  787.  
  788.     if(!strcmp(opt,"m")) 
  789.      { if (!do_melde) do_melde=1;
  790.        else error(E_ARG);
  791.        continue;
  792.      }
  793.  
  794.     if(!strcmp(opt,"crop")) 
  795.      { if (!do_crop) do_crop=1;
  796.        else error(E_ARG);
  797.        continue;
  798.      }
  799.  
  800.     if(!strcmp(opt,"pos")) 
  801.      { if (!print_pos) print_pos=1;
  802.        else error(E_ARG);
  803.        continue;
  804.      }
  805.  
  806.     if(!strcmp(opt,"rep")) 
  807.      { if (!do_rep) do_rep=1;
  808.        else error(E_ARG);
  809.        continue;
  810.      }
  811.  
  812. /****  Orientation options ****/
  813.  
  814.     if(!strcmp(opt,"n"))
  815.      {if (turn == T_UNSPEC) turn=T_NONE;
  816.       else error(E_ARG);
  817.       continue;
  818.      }
  819.  
  820.     if(!strcmp(opt,"r"))
  821.      {if (turn == T_UNSPEC) turn=T_RIGHT;
  822.       else error(E_ARG);
  823.       continue;
  824.      }
  825.  
  826.     if(!strcmp(opt,"l"))
  827.      {if (turn == T_UNSPEC) turn=T_LEFT;
  828.       else error(E_ARG);
  829.       continue;
  830.      }
  831.  
  832.     if(!strcmp(opt,"h"))
  833.      {if (turn == T_UNSPEC) turn=T_HEAD;
  834.       else error(E_ARG);
  835.       continue;
  836.      }
  837.  
  838.     if(!strcmp(opt,"a"))
  839.      {if (turn == T_UNSPEC) turn=T_AUTO;
  840.       else error(E_ARG);
  841.       continue;
  842.      }
  843.  
  844.     if(!strcmp(opt,"vert"))
  845.      {if (!flvert) flvert=1;
  846.       else error(E_ARG);
  847.       continue;
  848.      }
  849.  
  850.     if(!strcmp(opt,"hori"))
  851.      {if (!flhori) flhori=1;
  852.       else error(E_ARG);
  853.       continue;
  854.      }
  855.  
  856.  
  857.  
  858.  
  859.  
  860.  
  861. /**** Output options ****/
  862.  
  863.  
  864.     if((!strcmp(opt,"ppm")) || (!strcmp(opt,"PPM")))
  865.      { if (outfor == O_UNSPEC) outfor=O_PPM;
  866.        else error(E_ARG);
  867.        continue;
  868.      }
  869.  
  870.     if((!strcmp(opt,"pgm")) || (!strcmp(opt,"PGM")))
  871.      { if (outfor == O_UNSPEC) outfor=O_PGM;
  872.        else error(E_ARG);
  873.        continue;
  874.      }
  875.  
  876.     if(!strcmp(opt,"ycc")) 
  877.      { if (outfor == O_UNSPEC) outfor=O_YCC;
  878.        else error(E_ARG);
  879.        continue;
  880.      }
  881.  
  882.     if((!strcmp(opt,"ps")) || (!strcmp(opt,"PS")))
  883.      { if (outfor == O_UNSPEC) outfor=O_PS;
  884.        else error(E_ARG);
  885.        continue;
  886.      }
  887.  
  888.     if((!strcmp(opt,"eps")) || (!strcmp(opt,"EPS")))
  889.      { if (outfor == O_UNSPEC) outfor=O_EPS;
  890.        else error(E_ARG);
  891.        continue;
  892.      }
  893.  
  894.     if((!strcmp(opt,"psg")) || (!strcmp(opt,"PSG")))
  895.      { if (outfor == O_UNSPEC) outfor=O_PSG;
  896.        else error(E_ARG);
  897.        continue;
  898.      }
  899.  
  900.     if((!strcmp(opt,"epsg")) || (!strcmp(opt,"EPSG")))
  901.      { if (outfor == O_UNSPEC) outfor=O_EPSG;
  902.        else error(E_ARG);
  903.        continue;
  904.      }
  905.  
  906.     if((!strcmp(opt,"psd")) || (!strcmp(opt,"PSD")))
  907.      { if (outfor == O_UNSPEC) outfor=O_PSD;
  908.        else error(E_ARG);
  909.        continue;
  910.      }
  911.  
  912.     if((!strcmp(opt,"epsd")) || (!strcmp(opt,"EPSD")))
  913.      { if (outfor == O_UNSPEC) outfor=O_EPSD;
  914.        else error(E_ARG);
  915.        continue;
  916.      }
  917.  
  918.     if((!strcmp(opt,"jpeg")) || (!strcmp(opt,"JPEG")))
  919.      { if (outfor == O_UNSPEC) outfor=O_JPEG;
  920.        else error(E_ARG);
  921.        continue;
  922.      }
  923.  
  924.     if(!strcmp(opt,"quality" ))
  925.      { if(argc<1) error(E_ARG);
  926.        QUALITY_SET=1;
  927.        if((sscanf(*argv,SSFLTPT,&JPEG_QUALITY))!=1) error(E_ARG);
  928.        if(JPEG_QUALITY <= 0.0) error(E_OPT);
  929.        ASKIP;
  930.        continue;
  931.      }
  932.  
  933.    if(!strcmp(opt,"maxmemory" ))
  934.      { if(argc<1) error(E_ARG);
  935.        MAXMEMORY_SET=1;
  936.        if((sscanf(*argv,SSFLTPT,&JPEG_MAXMEMORY))!=1) error(E_ARG);
  937.        if(JPEG_MAXMEMORY <= 0.0) error(E_OPT);
  938.        ASKIP;
  939.        continue;
  940.      }
  941.  
  942.    if((!strcmp(opt,"optimize")) || (!strcmp(opt,"OPTIMIZE")))
  943.      { OPTIMIZE_JPEG = 1;
  944.        continue;
  945.      }
  946.  
  947.  
  948.     if(!strcmp(opt,"pl" ))
  949.      { if(argc<1) error(E_ARG);
  950.        if((sscanf(*argv,SSFLTPT,&PAPER_LEFT))!=1) error(E_ARG);
  951.        ASKIP;
  952.        continue;
  953.      }
  954.  
  955.     if(!strcmp(opt,"pb" ))
  956.      { if(argc<1) error(E_ARG);
  957.        if((sscanf(*argv,SSFLTPT,&PAPER_BOTTOM))!=1) error(E_ARG);
  958.        ASKIP;
  959.        continue;
  960.      }
  961.  
  962.  
  963.     if(!strcmp(opt,"pw" ))
  964.      { if(argc<1) error(E_ARG);
  965.        PSIZE_SET=1;
  966.        if((sscanf(*argv,SSFLTPT,&PAPER_WIDTH))!=1) error(E_ARG);
  967.        ASKIP;
  968.        continue;
  969.      }
  970.  
  971.     if(!strcmp(opt,"ph" ))
  972.      { if(argc<1) error(E_ARG);
  973.        PSIZE_SET=1;
  974.        if((sscanf(*argv,SSFLTPT,&PAPER_HEIGHT))!=1) error(E_ARG);
  975.        ASKIP;
  976.        continue;
  977.      }
  978.  
  979.  
  980.     if(!strcmp(opt,"fak" ))
  981.      { if(argc<1) error(E_ARG);
  982.        FAK_SET=1;
  983.        if((sscanf(*argv,SSFLTPT,&PRINTER_FAK))!=1) error(E_ARG);
  984.        if(PRINTER_FAK <= 0.0) error(E_OPT);
  985.        if(PRINTER_FAK >  1000.0) error(E_OPT);
  986.        ASKIP;
  987.        continue;
  988.      }
  989.  
  990.  
  991.  
  992. /**** Color model options ****/
  993.  
  994.     if(!strcmp(opt,"c0")) 
  995.      { if (corrmode == C_UNSPEC) corrmode = C_LINEAR;
  996.        else error(E_ARG);
  997.        continue;
  998.      }
  999.  
  1000.     if(!strcmp(opt,"c-")) 
  1001.      { if (corrmode == C_UNSPEC) corrmode = C_DARK;
  1002.        else error(E_ARG);
  1003.        continue;
  1004.      }
  1005.  
  1006.     if(!strcmp(opt,"c+")) 
  1007.      { if (corrmode == C_UNSPEC) corrmode = C_BRIGHT;
  1008.        else error(E_ARG);
  1009.        continue;
  1010.      }
  1011.  
  1012.    
  1013. /**** Subrectangel option ****/
  1014.     
  1015.     if(!strcmp(opt,"S"))
  1016.      { if (suba1) error(E_ARG);
  1017.        if(argc<2) error(E_ARG);
  1018.        suba1=argv[0];
  1019.        ASKIP;
  1020.        suba2=argv[0];
  1021.        ASKIP;
  1022.        continue;
  1023.      }
  1024.  
  1025.  
  1026. /**** Resolution options ****/
  1027.    
  1028.     if((!strcmp(opt,"Base/16")) || (!strcmp(opt,"1"))  || (!strcmp(opt,"128x192")))
  1029.      { if (size == S_UNSPEC) size = S_Base16;
  1030.        else error(E_ARG);
  1031.        continue;
  1032.      }
  1033.     if((!strcmp(opt,"Base/4" )) || (!strcmp(opt,"2"))  || (!strcmp(opt,"256x384")))
  1034.      { if (size == S_UNSPEC) size = S_Base4;
  1035.        else error(E_ARG);
  1036.        continue;
  1037.      }
  1038.     if((!strcmp(opt,"Base"   )) || (!strcmp(opt,"3"))  || (!strcmp(opt,"512x768")))
  1039.      { if (size == S_UNSPEC) size = S_Base;
  1040.        else error(E_ARG);
  1041.        continue;
  1042.      }
  1043.     if((!strcmp(opt,"4Base"  )) || (!strcmp(opt,"4"))  || (!strcmp(opt,"1024x1536")))
  1044.      { if (size == S_UNSPEC) size = S_4Base;
  1045.        else error(E_ARG);
  1046.        continue;
  1047.      }
  1048.     if((!strcmp(opt,"16Base" )) || (!strcmp(opt,"5"))  || (!strcmp(opt,"2048x3072")))
  1049.      { if (size == S_UNSPEC) size = S_16Base;
  1050.        else error(E_ARG);
  1051.        continue;
  1052.      }
  1053.  
  1054.     if((!strcmp(opt,"64Base" )) || (!strcmp(opt,"6"))  || (!strcmp(opt,"4096x6144")))
  1055.      { if (size == S_UNSPEC) size = S_64Base;
  1056.        else error(E_ARG);
  1057. /*
  1058.        if(argc<1) error(E_ARG);
  1059.        dir64=argv[0];
  1060.        ASKIP;
  1061. */
  1062.        continue;
  1063.      }
  1064.  
  1065.     if((!strcmp(opt,"Overview" )) || (!strcmp(opt,"0"))  || (!strcmp(opt,"O")))
  1066.      { if (size == S_UNSPEC) size = S_Over;
  1067.        else error(E_ARG);
  1068.        continue;
  1069.      }
  1070.  
  1071.     if((!strcmp(opt,"Contact" )) || (!strcmp(opt,"C")))
  1072.      { if (size == S_UNSPEC) size = S_Contact;
  1073.        else error(E_ARG);
  1074.        if(argc<2) error(E_ARG);
  1075.        if((sscanf(*argv,"%d",&contsize))!=1) error(E_ARG);
  1076.        ASKIP;
  1077.        if     (!strcmp(*argv,"n")) contori=T_NONE;
  1078.        else if(!strcmp(*argv,"r")) contori=T_RIGHT;
  1079.        else if(!strcmp(*argv,"l")) contori=T_LEFT;
  1080.        else if(!strcmp(*argv,"h")) contori=T_HEAD;
  1081.        else error(E_ARG);
  1082.        ASKIP;
  1083.  
  1084.        continue;
  1085.      }
  1086.  
  1087.    fprintf(stderr,"Unknown option: -%s\n",opt);
  1088.    error(E_ARG);
  1089.    }
  1090.  
  1091.   
  1092.   if(argc<1) error(E_ARG);
  1093.   pcdname= *argv;
  1094.   ASKIP;
  1095.  
  1096.   if(argc>0) 
  1097.    {ppmname= *argv;
  1098.     ASKIP;
  1099.    }
  1100.   
  1101.   if(argc>0) error(E_ARG);
  1102.  
  1103.  
  1104.  }
  1105. #undef ASKIP
  1106.  
  1107.  
  1108.  
  1109.  
  1110.  
  1111.  
  1112.  
  1113.  
  1114.  
  1115.  
  1116. static void checkin(void)
  1117.  { 
  1118.    if (do_info || (turn==T_AUTO)) 
  1119.      { SEEK(1);
  1120.        EREADBUF;
  1121.      }
  1122.  
  1123.     if(turn==T_AUTO) 
  1124.      {
  1125.       switch(sbuffer[0xe02 & 0x7ff]&0x03)
  1126.        {case 0x00: turn=T_NONE;  break;
  1127.         case 0x01: turn=T_LEFT;  break;
  1128.         case 0x02: turn=T_HEAD;  break;
  1129.         case 0x03: turn=T_RIGHT; break;
  1130.         default: error(E_TCANT);
  1131.        }
  1132.       }
  1133.  
  1134.     if(do_info) druckeid();
  1135.  
  1136.  }
  1137.  
  1138.  
  1139.  
  1140. /************************** file access functions **************/
  1141.  
  1142. int READ(uBYTE *ptr,int n)
  1143.  {int d;
  1144.   if(!n) return 1;
  1145.   bufpos+=n;
  1146.   for(;;)
  1147.    {d=fread((char *)ptr,1,n,fin);
  1148.     if(d<1) return 0;
  1149.     n-=d;
  1150.     if (!n) break;
  1151.     ptr+=d;
  1152.    }
  1153.   return 1;
  1154.  }
  1155.  
  1156. static int friss(int n)
  1157.  {int d;
  1158.  
  1159.   while(n>0)
  1160.    {
  1161.     d= n>sizeof(sbuffer) ? sizeof(sbuffer) : n;
  1162.     n-=d;
  1163.     if(READ(sbuffer,d) !=1) return 1;
  1164.    }
  1165.  
  1166.   return 0;
  1167.  }
  1168.  
  1169.  
  1170. void SEEK(int x)
  1171.  {
  1172.   x *= SECSIZE;
  1173.   if(x<bufpos) error(E_INTERN);
  1174.   if(x==bufpos) return;
  1175.  
  1176.   if(emulate_seek)
  1177.    {if(friss(x-bufpos)) error(E_READ);
  1178.     if(x!=bufpos) error(E_INTERN);
  1179.    }
  1180.   else
  1181.    {bufpos=x;
  1182.     if (fseek(fin,x,0)) error(E_READ);
  1183.    }
  1184. #ifdef DEBUG
  1185.   fprintf(stderr,"S-Position %x\n",bufpos);
  1186. #endif
  1187.  
  1188.  }
  1189.  
  1190.  
  1191.  
  1192. int SKIPn(int n)
  1193.  {
  1194.   if(!n) return 0;
  1195.   if(n<0) error(E_INTERN);
  1196.     
  1197.   if(emulate_seek)
  1198.    {return friss(n);
  1199.    }
  1200.   else
  1201.    {bufpos+=n;
  1202.     return fseek(fin,(n),1);
  1203.    }
  1204.  }
  1205.  
  1206.  
  1207.  
  1208.  
  1209.  
  1210. /************************** size control functions **************/
  1211.  
  1212. #define ISDIGIT(x) (((x)>='0') && ((x)<='9'))
  1213.  
  1214. static void number(char **s,char **i,char **f)
  1215.  {char *p;
  1216.  
  1217.   p= *s;
  1218.   (*i)=(*f)=0;
  1219.  
  1220.   if(!ISDIGIT(*p)) error(E_SUBR);
  1221.   while(ISDIGIT(*p)) p++;
  1222.   if(*p != '.') 
  1223.    { *i=*s;
  1224.      *s=p; 
  1225.      return;
  1226.    }
  1227.   p++;
  1228.   if(!ISDIGIT(*p)) error(E_SUBR);
  1229.   while(ISDIGIT(*p)) p++;
  1230.   *f=*s;
  1231.   *s=p;  
  1232.  }
  1233.  
  1234. static sdim makedim(sdim full,char *i,char *f)
  1235.  {sdim val;
  1236.   FLTPT fl;
  1237.  
  1238.   if(i) 
  1239.    {if(f) error(E_INTERN);
  1240.     if(sscanf(i,"%u",&val) != 1) error(E_SUBR);
  1241.     if((val<0) || (val >full)) error(E_SUBR);
  1242.     return val;
  1243.    }
  1244.   else
  1245.    {if(!f) error(E_INTERN);
  1246.     if(sscanf(f,SSFLTPT,&fl) != 1) error(E_SUBR);
  1247.     if((fl < 0.0) || (fl > 1.0)) error(E_SUBR);
  1248.     val= full * fl + 0.5;
  1249.     return val;
  1250.    }
  1251.  }
  1252.  
  1253. /*
  1254. #define xsMASK (~7)
  1255. #define sMASK (~15)
  1256. */
  1257. static void sizealign(char *str,dim full,
  1258.                       dim *rdoff,dim *rdlen,dim *imoff,dim *imlen,dim sMASK)
  1259.  {char *i1,*f1,*tr,*i2,*f2,*ptr;
  1260.   int vonbis=0;
  1261.   sdim von,len,rest;
  1262.  
  1263.   i1=f1=tr=i2=f2=0;
  1264.  
  1265.   ptr=str;
  1266.   number(&ptr,&i1,&f1);
  1267.  
  1268.   if(*ptr == '-') vonbis=1;
  1269.   else if (*ptr == '+') vonbis=0;
  1270.   else error(E_SUBR);
  1271.   ptr++;
  1272.  
  1273.   number(&ptr,&i2,&f2);
  1274.   if(*ptr) error(E_SUBR);
  1275.  
  1276.   von=makedim(full,i1,f1);
  1277.   len=makedim(full,i2,f2);
  1278.   if(vonbis) len-=von;
  1279.   rest=full-von-len;
  1280.  
  1281.   if((von<0) || (len<1) || (rest<0)) error(E_SUBR);
  1282.   
  1283.   *imlen = (dim) len;
  1284.  
  1285.   *rdoff = (dim) (von & sMASK); 
  1286.   *rdlen = full - *rdoff - ((dim)( rest & sMASK) );
  1287.  
  1288.   *imoff = ((dim) von) - *rdoff;
  1289.  
  1290.  }
  1291.  
  1292.  
  1293. static void sizecontrol(sizeinfo *si,dim w,dim h,dim sMASK)
  1294.  {
  1295.   si->w=w;
  1296.   si->h=h;
  1297.  
  1298.   if(!suba1)
  1299.    {
  1300.     si->rdhlen=w;
  1301.     si->rdvlen=h;
  1302.     si->rdhoff=0;
  1303.     si->rdvoff=0;
  1304.     si->imhlen=0;
  1305.     si->imvlen=0;
  1306.     si->imhoff=0;
  1307.     si->imvoff=0;
  1308.    }
  1309.   else
  1310.    {sizealign(suba1,w,&si->rdhoff,&si->rdhlen,&si->imhoff,&si->imhlen,sMASK);
  1311.     sizealign(suba2,h,&si->rdvoff,&si->rdvlen,&si->imvoff,&si->imvlen,sMASK);
  1312.    }
  1313.  
  1314. #ifdef DEBUG
  1315.   fprintf(stderr,"Align: %5d %5d \n",si->w,si->h);
  1316.   fprintf(stderr,"Align: %5d %5d %5d %5d \n",si->rdhoff,si->rdhlen,si->rdvoff,si->rdvlen);
  1317.   fprintf(stderr,"Align: %5d %5d %5d %5d \n",si->imhoff,si->imhlen,si->imvoff,si->imvlen);
  1318. #endif
  1319.  
  1320.  }
  1321.  
  1322.  
  1323.  
  1324. /* Thanks to James Pearson for writing get_dir64 */
  1325.  
  1326. /* finds dir64 from the given input filename 
  1327.    Had to change DIRSEP from a string to a character */
  1328. static void get_dir64(void)
  1329. {
  1330.     char    name[32];
  1331.     char    *n, *p, *d;
  1332.     
  1333.     d = dir64;
  1334.  
  1335.     /* find if input filename includes a path */
  1336.     if ((p = strrchr(pcdname,DIRSEP)) == 0)
  1337.         p = pcdname;
  1338.     else
  1339.     {
  1340.         /* copy path to start of dir64 */
  1341.         n = pcdname;
  1342.         p++;
  1343.         while (n < p)
  1344.             *d++ = *n++;
  1345.     }
  1346.  
  1347.     /* get first part of filename (the bit before .pcd) */
  1348.     n = name; 
  1349.     while (*p != '.' && *p != '\0')
  1350.         *n++ = *p++;
  1351.  
  1352.     *n = '\0';
  1353.  
  1354. #ifdef DEBUG
  1355.     *d = '\0';
  1356.     fprintf(stderr,"Path64: %s\nName64: %s\n",dir64,name);
  1357. #endif
  1358.  
  1359.     /* construct path */
  1360. #ifdef SMALLNAMES
  1361.     sprintf(d,"..%cipe%c%s%c64base",DIRSEP,DIRSEP,name,DIRSEP);
  1362. #else
  1363.     sprintf(d,"..%cIPE%c%s%c64BASE",DIRSEP,DIRSEP,name,DIRSEP);
  1364. #endif
  1365. }
  1366.