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