home *** CD-ROM | disk | FTP | other *** search
/ Amiga ISO Collection / AmigaUtilCD1.iso / CDRom / fotocd11.lha / src / photocdaga / main.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-04-12  |  12.4 KB  |  588 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. /* Main part of PhotoCDAGA */
  12.  
  13.  
  14. /* NOTE: Don't use this file for compiling hpcdtoppm, it is heavily */
  15. /* modified.  (By me, Günther Röhrich)                              */
  16. /* EMAIL: Guenther@studbox.uni-stuttgart.de  */
  17.  
  18.  
  19. #include "hpcdtoppm.h"
  20. #include <signal.h>
  21. #include <stdlib.h>
  22.  
  23. char  *ver = "\0$VER: PhotoCDAGA 1.1 (11.4.95)";
  24.  
  25. uBYTE sbuffer[SECSIZE];
  26.  
  27. enum TURNS  turn     = T_UNSPEC;
  28. enum TURNS  contori  = T_UNSPEC;
  29. enum SIZES  size     = S_UNSPEC;
  30. enum OUTFOR outfor   = O_UNSPEC;
  31. enum CORR   corrmode = C_UNSPEC;
  32.  
  33. char *pcdname=NULL;
  34. char *ppmname=NULL;
  35. char *MapFileName;
  36. char *BaseName = NULL;
  37. static FILE  *fin=NULL,*fout=NULL;
  38. static char    *suba1=0,*suba2=0;
  39. static implane Luma, Chroma1,Chroma2;
  40. static implane *PLuma=NULL,*PChroma1=NULL,*PChroma2=NULL;
  41. sINT monochrome=0,do_overskip=0,bufpos=0,print_pos=0,emulate_seek=0,do_melde=0,do_crop=0,do_sharp=0,do_rep=0;
  42. sINT flhori=0,flvert=0,do_info=0,bildnr,startbild=0;
  43.  
  44. extern int VGAenable;
  45.  
  46. #define PrintPos(x) {if(print_pos) fprintf(stderr,"File-Offset: %8d = %8x (hex) = %d (sec)\n",(x),(x),(x)/0x800);}
  47.  
  48.  
  49. static void sizecontrol(sizeinfo *,dim,dim,dim sMASK);
  50. static void f_1 (dim,dim,sINT,sINT);
  51. static void f_3 (dim,dim,sINT);
  52. static void f_ov(dim w,dim h,sINT offset,sINT imsize);
  53. static void openoutput(void);
  54. static void checkin(void);
  55.  
  56. void close_all(void)
  57. {
  58.   if(fin) fclose(fin);
  59.  
  60.   if(fout) fclose(fout);
  61.  
  62.   CloseDisplay();
  63. }
  64.  
  65. #ifdef __GNUC__
  66. /* this is called when CTRL-C occurs */
  67. void GCCAbortHandler(void)
  68. {
  69.   printf("Interrupted by user.\n");
  70.   exit(10);
  71. }
  72. #endif
  73.  
  74. void main(int argc, char **argv)
  75. {
  76.  int i,start=2;
  77.  
  78.  #ifdef __GNUC__            /* Modify GNU C CTRL-C handling */
  79.  signal(SIGINT, GCCAbortHandler);
  80.  #endif
  81.  printf("PhotoCDAGA 1.1 (c) by Hadmut Danisch, Günther Röhrich\n");
  82.  /* printf("Preliminary release. DO NOT SPREAD IT!\n"); */
  83.  
  84.  if(argc < 2) error(E_ARG);
  85.  
  86.  MapFileName = malloc(strlen(argv[1])+5);
  87.  if(MapFileName == NULL) error(E_MEM);
  88.  strcpy(MapFileName, argv[1]); /* create a copy of the file name */
  89.  
  90.  pcdname=argv[1];
  91.  
  92.  if(argc > 2)
  93.  {
  94.    if(argv[2][0] != '-')
  95.    {
  96.      ppmname = argv[2];
  97.      start = 3;
  98.    }
  99.  }
  100.  
  101.  /* default settings */
  102.  outfor = O_DCOLOR; 
  103.  corrmode = C_LINEAR;
  104.  turn = T_AUTO;
  105.  size = S_Base;
  106.  
  107.  for(i=start; i<argc; i++)
  108.  {
  109.  if(!strncmp(argv[i], "-x", 2)) do_overskip=1;
  110.  
  111.  else if(!strncmp(argv[i], "-s", 2)) do_sharp=1;
  112.  
  113.  else if(!strncmp(argv[i], "-c", 2)) do_crop=1; 
  114.  
  115.  else if(!strncmp(argv[i], "-n", 2)) turn=T_NONE;
  116.  
  117.  else if(!strncmp(argv[i], "-r", 2)) turn=T_RIGHT;
  118.  
  119.  else if(!strncmp(argv[i], "-l", 2)) turn=T_LEFT;
  120.  
  121.  else if(!strncmp(argv[i], "-h", 2)) turn=T_HEAD;
  122.  
  123.  else if(!strncmp(argv[i], "-m", 2)) do_melde = 1;
  124.  
  125.  else if(!strncmp(argv[i], "-c-" ,3)) corrmode=C_DARK;
  126.  
  127.  else if(!strncmp(argv[i], "-c+" ,3)) corrmode=C_BRIGHT;
  128.  
  129.  else if(!strncmp(argv[i], "-ppm",3)) outfor=O_PPM;
  130.  
  131.  else if(!strncmp(argv[i], "-pgm" ,3)) outfor=O_PGM;
  132.  
  133.  else if(!strncmp(argv[i], "-gray", 5)) outfor=O_DGRAY;
  134.  
  135.  else if(!strncmp(argv[i], "-vga", 4)) VGAenable = 1;
  136.  
  137.  else if(!strncmp(argv[i], "-1", 2)) size = S_Base16;
  138.  
  139.  else if(!strncmp(argv[i], "-2", 2)) size = S_Base4;
  140.  
  141.  else if(!strncmp(argv[i], "-3", 2)) size = S_Base;
  142.  
  143.  else if(!strncmp(argv[i], "-0", 2))
  144.  {
  145.    size = S_Over;
  146.    if(argc == i+1) error(E_ARG);
  147.    startbild = (sINT)strtol(argv[i+1], NULL, 0);
  148.    if(startbild < 1) error(E_ARG);
  149.    i++;
  150.  }
  151.    
  152.  else if(!strncmp(argv[i], "-b", 2))
  153.  {
  154.    if(argc == i+1) error(E_ARG); /* last argument */
  155.    BaseName = argv[i+1];
  156.    i++;
  157.  }
  158.  
  159.  else error(E_ARG);
  160.  }
  161.  
  162.  
  163.  
  164.  fin=fopen(pcdname, "r");
  165.  if(fin == NULL)
  166.  {
  167.    printf("Could not open PhotoCD file.\n");
  168.    exit(10);
  169.  }
  170.  
  171.  
  172.  monochrome = (outfor==O_PGM) || (outfor==O_DGRAY);
  173.  
  174.  if(monochrome && do_overskip) error(E_ARG);
  175.  
  176.  if(start == 3 && (outfor != O_PGM && outfor != O_PPM)) error(E_ARG);
  177.  
  178.  if(start == 2 && (outfor == O_PGM || outfor == O_PPM)) error(E_ARG);
  179.  
  180.  if(size == S_Over)
  181.  {
  182.    if(outfor == O_DCOLOR) outfor = O_DOVER_COLOR;
  183.    else if(outfor == O_DGRAY) outfor = O_DOVER_GRAY;
  184.    else error(E_ARG);
  185.  }
  186.  
  187.  if(size != S_Over) checkin();
  188.  
  189.  PLuma = &Luma;
  190.  PChroma1= monochrome ? 0 : &Chroma1; 
  191.  PChroma2= monochrome ? 0 : &Chroma2; 
  192.  
  193.  switch(size)
  194.  {
  195.    case S_Base16: f_1(BaseW/4,BaseH/4,L_Head,(L_Head+L_Base16));
  196.                   break;
  197.  
  198.    case S_Base4:  f_1(BaseW/2,BaseH/2,(L_Head+L_Base16),(L_Head+L_Base16+L_Base4));
  199.                   break;
  200.  
  201.    case S_Base:   f_3(BaseW,BaseH,(L_Head+L_Base16+L_Base4));
  202.                   break;
  203.  
  204.    case S_Over:   f_ov(BaseW/4,BaseH/4,5,SeBase16);
  205.                   break;
  206.  
  207.    default: error(E_INTERN);
  208.  }
  209.  
  210.    close_all();
  211.  
  212.  
  213.  exit(0);
  214. }
  215.  
  216.  
  217. static void f_1(dim w,dim h,sINT normal,sINT overskip)
  218. {
  219.  sizeinfo si;
  220.  
  221.  sizecontrol(&si,w,h,~3);
  222.  
  223.  planealloc(PLuma   ,si.rdhlen,si.rdvlen);
  224.  if (!monochrome) planealloc(PChroma1,si.rdhlen,si.rdvlen);
  225.  if (!monochrome) planealloc(PChroma2,si.rdhlen,si.rdvlen);
  226.  
  227.  PrintPos(normal*SECSIZE);
  228.  SEEK(normal+1);                   
  229.       
  230.  if(!do_overskip)
  231.  {
  232.    error(readplain(&si,1,PLuma,PChroma1,PChroma2));
  233.    if (!monochrome) 
  234.    {
  235.      interpolate(PChroma1);
  236.      interpolate(PChroma2);
  237.    }
  238.  }
  239.  else
  240.  {
  241.     error(readplain(&si,1,PLuma,nullplane,nullplane));
  242.     SEEK(overskip+1);
  243.     error(readplain(&si,2,nullplane,PChroma1,PChroma2));
  244.  }
  245.  
  246.  colconvert(&si,PLuma,PChroma1,PChroma2);
  247.  /* Now Luma holds red, Chroma1 hold green, Chroma2 holds blue */
  248.  
  249.  if(outfor == O_PPM || outfor == O_PGM) openoutput();
  250.  
  251.  writepicture(fout,&si,PLuma,PChroma1,PChroma2,turn);
  252. }
  253.  
  254.  
  255. static void f_3(dim w,dim h,sINT normal)
  256.  {sINT cd_offset,cd_offhelp;
  257.   sizeinfo si;
  258.  
  259.   sizecontrol(&si,w,h,~3);
  260.  
  261.   PrintPos(normal*SECSIZE);
  262.   SEEK(normal+1);
  263.  
  264.   if(!do_overskip)
  265.     {                 planealloc(PLuma   ,si.rdhlen,si.rdvlen);
  266.      if (!monochrome) planealloc(PChroma1,si.rdhlen,si.rdvlen);
  267.      if (!monochrome) planealloc(PChroma2,si.rdhlen,si.rdvlen);
  268.  
  269.      error(readplain(&si,1,PLuma,PChroma1,PChroma2));
  270.       if (!monochrome) 
  271.         {interpolate(PChroma1);
  272.          interpolate(PChroma2);
  273.         }
  274.     }
  275.    else
  276.     {planealloc(PLuma   ,  si.rdhlen,  si.rdvlen);
  277.      planealloc(PChroma1,2*si.rdhlen,2*si.rdvlen);
  278.      planealloc(PChroma2,2*si.rdhlen,2*si.rdvlen);
  279.  
  280.      error(readplain(&si,1,PLuma,PChroma1,PChroma2));
  281.      interpolate(PChroma1);
  282.      interpolate(PChroma2);
  283.      interpolate(PChroma1);
  284.      interpolate(PChroma2);
  285.  
  286.      cd_offset=Skip4Base();
  287.      SEEK(cd_offset+10);          EREADBUF;    cd_offhelp=(((uINT)sbuffer[2])<<8)|sbuffer[3];
  288.      SEEK(cd_offset+12);          readhqt(3);
  289.      SEEK(cd_offset+cd_offhelp);  decode(&si,4,nullplane,PChroma1,PChroma2,1);
  290.  
  291.      halve(PChroma1);
  292.      halve(PChroma2);
  293.     }
  294.   colconvert(&si,PLuma,PChroma1,PChroma2);
  295.   /* Now Luma holds red, Chroma1 hold green, Chroma2 holds blue */
  296.  
  297.   if(outfor == O_PPM || outfor == O_PGM) openoutput();
  298.   writepicture(fout,&si,PLuma,PChroma1,PChroma2,turn);
  299.  
  300.  }
  301.  
  302.  static uBYTE hbuf[SECSIZE];
  303.  
  304.  static void f_ov(dim w,dim h,sINT offset,sINT imsize)
  305.  {sINT bilder, endbild;
  306.   dim wx,hx;
  307.   enum ERRORS eret;
  308.   enum TURNS imorient;
  309.   sizeinfo si;
  310.   
  311.   sizecontrol(&si,w,h,~3);
  312.  
  313.   wx=w; hx=h;
  314.  
  315.                    planealloc(PLuma   ,si.rdhlen,si.rdvlen);
  316.   if (!monochrome) planealloc(PChroma1,si.rdhlen,si.rdvlen);
  317.   if (!monochrome) planealloc(PChroma2,si.rdhlen,si.rdvlen);
  318.  
  319.  
  320.   SEEK(0); 
  321.   if(READ(hbuf,sizeof(hbuf))<1) error(E_READ);
  322.  
  323.   bilder=(((sINT) hbuf[10])<<8) | hbuf[11];
  324.  
  325.   if(startbild > bilder)
  326.   {
  327.     fprintf(stderr, "There are only %d pictures in the overview file.\n", bilder);
  328.     error(E_PICNUM);
  329.   }
  330.    
  331.   endbild = startbild+15;
  332.   if(endbild > bilder) endbild = bilder;
  333.  
  334.    for(bildnr=startbild-1;bildnr<endbild;bildnr++)
  335.    {w=wx;h=hx;
  336.     sizecontrol(&si,w,h,~3);
  337.     PLuma->im=PLuma->mp;
  338.     if(PChroma1) PChroma1->im=PChroma1->mp;
  339.     if(PChroma2) PChroma2->im=PChroma2->mp;
  340.  
  341.     SEEK(offset+imsize*bildnr);
  342.   
  343.     eret=readplain(&si,1,PLuma,PChroma1,PChroma2);
  344.     if(eret==E_READ) break;
  345.     error(eret);
  346.  
  347.     if(!monochrome)
  348.      {interpolate(PChroma1);
  349.       interpolate(PChroma2);
  350.      }
  351.  
  352.     colconvert(&si,PLuma,PChroma1,PChroma2);
  353.   
  354.     if(outfor == O_PPM || outfor == O_PGM) openoutput();
  355.  
  356.      switch(hbuf[12+bildnr] & 3)
  357.       {case 0:  imorient=T_NONE;  break;
  358.        case 1:  imorient=T_LEFT;  break;
  359.        case 2:  imorient=T_HEAD;  break;
  360.        case 3:  imorient=T_RIGHT; break;
  361.        default: imorient=T_NONE;
  362.       }
  363.  
  364.     
  365.     /* writepicture(fout,&si,PLuma,PChroma1,PChroma2,turn != T_AUTO ? turn : imorient); */
  366.     writepicture(fout,&si,PLuma,PChroma1,PChroma2,T_NONE);
  367.    }
  368.    FinalWait();
  369.    CloseDisplay();
  370.  }
  371.  
  372.  
  373.  
  374. #define ISDIGIT(x) (((x)>='0') && ((x)<='9'))
  375.  
  376. static void number(char **s,char **i,char **f)
  377.  {char *p;
  378.  
  379.   p= *s;
  380.   (*i)=(*f)=0;
  381.  
  382.   if(!ISDIGIT(*p)) error(E_SUBR);
  383.   while(ISDIGIT(*p)) p++;
  384.   if(*p != '.') 
  385.    { *i=*s;
  386.      *s=p; 
  387.      return;
  388.    }
  389.   p++;
  390.   if(!ISDIGIT(*p)) error(E_SUBR);
  391.   while(ISDIGIT(*p)) p++;
  392.   *f=*s;
  393.   *s=p;  
  394.  }
  395.  
  396. static sdim makedim(sdim full,char *i,char *f)
  397.  {sdim val;
  398.   FLTPT fl;
  399.  
  400.   if(i) 
  401.    {if(f) error(E_INTERN);
  402.     if(sscanf(i,"%u",&val) != 1) error(E_SUBR);
  403.     if((val<0) || (val >full)) error(E_SUBR);
  404.     return val;
  405.    }
  406.   else
  407.    {if(!f) error(E_INTERN);
  408.     if(sscanf(f,SSFLTPT,&fl) != 1) error(E_SUBR);
  409.     if((fl < 0.0) || (fl > 1.0)) error(E_SUBR);
  410.     val= full * fl + 0.5;
  411.     return val;
  412.    }
  413.  }
  414.  
  415.  
  416.  
  417. static void sizealign(char *str,dim full,
  418.                       dim *rdoff,dim *rdlen,dim *imoff,dim *imlen,dim sMASK)
  419.  {char *i1,*f1,*tr,*i2,*f2,*ptr;
  420.   int vonbis=0;
  421.   sdim von,len,rest;
  422.  
  423.   i1=f1=tr=i2=f2=0;
  424.  
  425.   ptr=str;
  426.   number(&ptr,&i1,&f1);
  427.  
  428.   if(*ptr == '-') vonbis=1;
  429.   else if (*ptr == '+') vonbis=0;
  430.   else error(E_SUBR);
  431.   ptr++;
  432.  
  433.   number(&ptr,&i2,&f2);
  434.   if(*ptr) error(E_SUBR);
  435.  
  436.   von=makedim(full,i1,f1);
  437.   len=makedim(full,i2,f2);
  438.   if(vonbis) len-=von;
  439.   rest=full-von-len;
  440.  
  441.   if((von<0) || (len<1) || (rest<0)) error(E_SUBR);
  442.   
  443.   *imlen = (dim) len;
  444.  
  445.   *rdoff = (dim) (von & sMASK); 
  446.   *rdlen = full - *rdoff - ((dim)( rest & sMASK) );
  447.  
  448.   *imoff = ((dim) von) - *rdoff;
  449.  
  450.  }
  451.  
  452.  
  453. static void sizecontrol(sizeinfo *si,dim w,dim h,dim sMASK)
  454. {
  455.   si->w=w;
  456.   si->h=h;
  457.  
  458.   if(!suba1)
  459.   {
  460.     si->rdhlen=w;
  461.     si->rdvlen=h;
  462.     si->rdhoff=0;
  463.     si->rdvoff=0;
  464.     si->imhlen=0;
  465.     si->imvlen=0;
  466.     si->imhoff=0;
  467.     si->imvoff=0;
  468.   }
  469.   else
  470.   {
  471.     sizealign(suba1,w,&si->rdhoff,&si->rdhlen,&si->imhoff,&si->imhlen,sMASK);
  472.     sizealign(suba2,h,&si->rdvoff,&si->rdvlen,&si->imvoff,&si->imvlen,sMASK);
  473.   }
  474.  
  475. #ifdef DEBUG
  476.   fprintf(stderr,"Align: %5d %5d \n",si->w,si->h);
  477.   fprintf(stderr,"Align: %5d %5d %5d %5d \n",si->rdhoff,si->rdhlen,si->rdvoff,si->rdvlen);
  478.   fprintf(stderr,"Align: %5d %5d %5d %5d \n",si->imhoff,si->imhlen,si->imvoff,si->imvlen);
  479. #endif
  480.  
  481. }
  482.  
  483.  
  484.  
  485. static void checkin(void)
  486.  { 
  487.    if (do_info || (turn==T_AUTO)) 
  488.      { SEEK(1);
  489.        EREADBUF;
  490.      }
  491.  
  492.     if(turn==T_AUTO) 
  493.      {
  494.       switch(sbuffer[0xe02 & 0x7ff]&0x03)
  495.        {case 0x00: turn=T_NONE;  break;
  496.         case 0x01: turn=T_LEFT;  break;
  497.         case 0x02: turn=T_HEAD;  break;
  498.         case 0x03: turn=T_RIGHT; break;
  499.         default: error(E_TCANT);
  500.        }
  501.       }
  502.  
  503.     if(do_info) druckeid();
  504.  
  505.  }
  506.  
  507.  
  508.  
  509. /************************** file access functions **************/
  510.  
  511. int READ(uBYTE *ptr,int n)
  512.  {int d;
  513.   if(!n) return 1;
  514.   bufpos+=n;
  515.   for(;;)
  516.    {d=fread((char *)ptr,1,n,fin);
  517.     if(d<1) return 0;
  518.     n-=d;
  519.     if (!n) break;
  520.     ptr+=d;
  521.    }
  522.   return 1;
  523.  }
  524.  
  525. static int friss(int n)
  526.  {int d;
  527.  
  528.   while(n>0)
  529.    {
  530.     d= n>sizeof(sbuffer) ? sizeof(sbuffer) : n;
  531.     n-=d;
  532.     if(READ(sbuffer,d) !=1) return 1;
  533.    }
  534.  
  535.   return 0;
  536.  }
  537.  
  538.  
  539. static void openoutput(void)
  540. {
  541.  if(ppmname)
  542.  {
  543.    fout=fopen(ppmname, "w");
  544.    if(fout == NULL)
  545.    {
  546.      printf("Could not open output file.\n");
  547.      exit(10L);
  548.    }
  549.  }
  550.  else error(E_INTERN);
  551. }
  552.  
  553.  
  554. void SEEK(int x)
  555.  {
  556.   x *= SECSIZE;
  557.   if(x<bufpos) error(E_INTERN);
  558.   if(x==bufpos) return;
  559.  
  560.   if(emulate_seek)
  561.    {if(friss(x-bufpos)) error(E_READ);
  562.     if(x!=bufpos) error(E_INTERN);
  563.    }
  564.   else
  565.    {bufpos=x;
  566.     if (fseek(fin,x,0)) error(E_READ);
  567.    }
  568. #ifdef DEBUG
  569.   fprintf(stderr,"S-Position %x\n",bufpos);
  570. #endif
  571.  
  572.  }
  573.  
  574. int SKIPn(int n)
  575.  {
  576.   if(!n) return 0;
  577.   if(n<0) error(E_INTERN);
  578.     
  579.   if(emulate_seek)
  580.    {return friss(n);
  581.    }
  582.   else
  583.    {bufpos+=n;
  584.     return fseek(fin,(n),1);
  585.    }
  586.  }
  587.  
  588.