home *** CD-ROM | disk | FTP | other *** search
/ Nebula 1 / Nebula One.iso / Graphics / Viewers / pCD0.3.4 / Source / Photo_CD.subproj / pcd.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-06-12  |  12.2 KB  |  511 lines

  1.  
  2. /* hpcdtoppm (Hadmut's pcdtoppm) v0.2
  3. *  Copyright (c) 1992 by Hadmut Danisch (danisch@ira.uka.de).
  4. *  Permission to use and distribute this software and its
  5. *  documentation for noncommercial use and without fee is hereby granted,
  6. *  provided that the above copyright notice appear in all copies and that
  7. *  both that copyright notice and this permission notice appear in
  8. *  supporting documentation. It is not allowed to sell this software in 
  9. *  any way. This software is not public domain.
  10. */
  11.  
  12.  
  13. /* define DEBUG for some debugging informations, just remove the x from xDEBUG */
  14. #define xDEBUG
  15.  
  16. /* define MELDUNG if you want to see what is happening and what takes time,
  17.    just remove the x from xMeldung */
  18. #define xMELDUNG
  19.  
  20.  
  21. /* define OWN_WRITE either here or by compiler-option if you don't want to use
  22.    the pbmplus-routines for writing */
  23. #define OWN_WRITE
  24.  
  25. /* If the own routines are used, this is the size of the buffer in bytes.
  26.    You can shrink if needed. */
  27. #define own_BUsize 50000
  28.  
  29.  
  30.  
  31.  
  32.  
  33.  
  34. #include <stdlib.h>        //  on NeXT, at least
  35. #include <string.h>        //  on NeXT, at least
  36. #include <stdio.h>
  37. #ifndef OWN_WRITE
  38. #include "ppm.h"
  39. #else
  40.  
  41. /* The header for the ppm-files */
  42. #define PPM_Header "P6\n%d %d\n255\n"
  43.  
  44.  
  45. #endif
  46.  
  47.  
  48.  
  49. typedef unsigned char uBYTE;
  50. typedef unsigned long dim;
  51.  
  52. #define BaseW ((dim)768)
  53. #define BaseH ((dim)512)
  54.  
  55. #define SECSIZE 0x800
  56.  
  57.  
  58.  
  59. #define SeHead   2
  60. #define L_Head   (1+SeHead)
  61.  
  62. #define SeBase16 18
  63. #define L_Base16 (1+SeBase16)
  64.  
  65. #define SeBase4  72
  66. #define L_Base4  (1+SeBase4)
  67.  
  68. #define SeBase   288
  69. #define L_Base   (1+SeBase)
  70.  
  71.  
  72.  
  73.  
  74.  
  75.  
  76. enum ERRORS { E_NONE,E_READ,E_WRITE,E_INTERN,E_ARG,E_OPT,E_MEM,E_HUFF,
  77.              E_SEQ,E_SEQ1,E_SEQ2,E_SEQ3,E_SEQ4,E_SEQ5,E_SEQ6,E_SEQ7,E_POS,E_IMP };
  78.  
  79. enum TURNS  { T_NONE,T_RIGHT,T_LEFT };
  80.  
  81. enum SIZES  { S_UNSPEC,S_Base16,S_Base4,S_Base,S_4Base,S_16Base,S_Over };
  82.  
  83. /* Default taken when no size parameter given */
  84. #define S_DEFAULT S_Base16
  85.  
  86. struct _implane
  87.  {dim  mwidth,mheight,
  88.        iwidth,iheight;
  89.   uBYTE *im;
  90.  };
  91. typedef struct _implane implane;
  92.  
  93.  
  94.  
  95. enum ERRORS readplain();
  96. void interpolate();
  97. // static void writepicture();
  98. void readhqt();
  99. void decode();
  100.  
  101. static FILE *fin=0,*fout=0;
  102. static char *ppmname=0;
  103. static uBYTE sbuffer[SECSIZE];
  104.  
  105.  
  106.  
  107.  
  108. /* Using preprocessor for inline-procs */
  109. #ifdef DEBUG
  110. #define SEEK(x) { if (fseek(fin,((x) * SECSIZE),0)) error(E_READ);\
  111.                   fprintf(stderr,"S-Position %x\n",ftell(fin)); }
  112. #else
  113. #define SEEK(x) { if (fseek(fin,((x) * SECSIZE),0)) error(E_READ);}
  114. #endif
  115.  
  116.  
  117. #define SKIP(n)  { if (fseek(fin,(n),1)) error(E_READ);}
  118. #define SKIPr(n) { if (fseek(fin,(n),1)) return(E_READ);}
  119.  
  120. #define READBUF   fread(sbuffer,sizeof(sbuffer),1,fin)
  121. #define READBUF_NeXT   fread(sbuffer,sizeof(sbuffer),1,NeXT_fin)
  122.  
  123. #define xTRIF(x,u,o,a,b,c) ((x)<(u)? (a) : ( (x)>(o)?(c):(b)  ))
  124. #define xNORM(x) x=TRIF(x,0,255,0,x,255)
  125. #define NORM(x) { if(x<0) x=0; else if (x>255) x=255;}
  126.  
  127. #ifdef MELDUNG
  128. #define melde(x) fprintf(stderr,x)
  129. #else
  130. #define melde(x)
  131. #endif
  132.  
  133.  
  134.  
  135.  
  136. void error(e)
  137.   enum ERRORS e;
  138.  {
  139.   
  140.   switch(e)
  141.    {case E_NONE:   return;
  142.     case E_IMP:    fprintf(stderr,"Sorry, Not yet implemented.\n"); break;
  143.     case E_READ:   fprintf(stderr,"Error while reading.\n"); break;
  144.     case E_WRITE:  fprintf(stderr,"Error while writing.\n"); break;
  145.     case E_INTERN: fprintf(stderr,"Internal error.\n"); break;
  146.     case E_ARG:    fprintf(stderr,"Arguments !\n"); 
  147.                    fprintf(stderr,"Usage: hpcdtoppm [options] pcd-file [ppm-file]\n");
  148.                    fprintf(stderr,"Opts:\n");
  149.                    fprintf(stderr,"     -i Give some (buggy) informations from fileheader\n");
  150.                    fprintf(stderr,"     -s Apply simple sharpness-operator on the Luma-channel\n");
  151.                    fprintf(stderr,"     -d Show differential picture only \n");
  152.                    fprintf(stderr,"     -r Rotate clockwise for portraits\n");
  153.                    fprintf(stderr,"     -l Rotate counter-clockwise for portraits\n");
  154.                    fprintf(stderr,"     -0 Extract thumbnails from Overview file\n");
  155.                    fprintf(stderr,"     -1 Extract  128x192  from Image file\n");
  156.                    fprintf(stderr,"     -2 Extract  256x384  from Image file\n");
  157.                    fprintf(stderr,"     -3 Extract  512x768  from Image file\n");
  158.                    fprintf(stderr,"     -4 Extract 1024x1536 from Image file\n");
  159.                    fprintf(stderr,"     -5 Extract 2048x3072 from Image file\n");
  160.                    break;
  161.     case E_OPT:    fprintf(stderr,"These Options are not allowed together.\n");break;
  162.     case E_MEM:    fprintf(stderr,"Not enough memory !\n"); break;
  163.     case E_HUFF:   fprintf(stderr,"Error in Huffman-Code-Table\n"); break;
  164.     case E_SEQ:    fprintf(stderr,"Error in Huffman-Sequence\n"); break;
  165.     case E_SEQ1:    fprintf(stderr,"Error1 in Huffman-Sequence\n"); break;
  166.     case E_SEQ2:    fprintf(stderr,"Error2 in Huffman-Sequence\n"); break;
  167.     case E_SEQ3:    fprintf(stderr,"Error3 in Huffman-Sequence\n"); break;
  168.     case E_SEQ4:    fprintf(stderr,"Error4 in Huffman-Sequence\n"); break;
  169.     case E_SEQ5:    fprintf(stderr,"Error5 in Huffman-Sequence\n"); break;
  170.     case E_SEQ6:    fprintf(stderr,"Error6 in Huffman-Sequence\n"); break;
  171.     case E_SEQ7:    fprintf(stderr,"Error7 in Huffman-Sequence\n"); break;
  172.     case E_POS:    fprintf(stderr,"Error in file-position\n"); break;
  173.     default:       fprintf(stderr,"Unknown error %d ???\n",e);break;
  174.    }
  175.   if(fin) fclose(fin);
  176.   if(fout && ppmname) fclose(fout);
  177.   exit(9);
  178.  }
  179.  
  180. void planealloc(p,width,height)
  181.   implane *p;
  182.   dim width,height;
  183.  {
  184.   p->iwidth=p->iheight=0;
  185.   p->mwidth=width;
  186.   p->mheight=height;
  187.  
  188.   p->im = ( uBYTE * ) malloc  (width*height*sizeof(uBYTE));
  189.   if(!(p->im)) error(E_MEM);
  190.  }
  191.  
  192. enum ERRORS readplain(w,h,l,c1,c2,fin)
  193.   FILE *fin;
  194.   dim w,h;
  195.   implane *l,*c1,*c2;
  196.  {dim i;
  197.   uBYTE *pl=0,*pc1=0,*pc2=0;
  198.   melde("readplain\n");
  199.  
  200.   if(l)
  201.    { if ((l->mwidth<w) || (l->mheight<h) || (!l->im)) error(E_INTERN);
  202.      l->iwidth=w;
  203.      l->iheight=h;
  204.      pl=l->im;
  205.    }
  206.  
  207.   if(c1)
  208.    { if ((c1->mwidth<w/2) || (c1->mheight<h/2) || (!c1->im)) error(E_INTERN);
  209.      c1->iwidth=w/2;
  210.      c1->iheight=h/2;
  211.      pc1=c1->im;
  212.    }
  213.  
  214.   if(c2)
  215.    { if ((c2->mwidth<w/2) || (c2->mheight<h/2) || (!c2->im)) error(E_INTERN);
  216.      c2->iwidth=w/2;
  217.      c2->iheight=h/2;
  218.      pc2=c2->im;
  219.    }
  220.  
  221.   for(i=0;i<h/2;i++)
  222.    {
  223.     if(pl)
  224.      { 
  225.        if(fread(pl,w,1,fin)<1) return(E_READ);
  226.        pl+= l->mwidth;
  227.  
  228.        if(fread(pl,w,1,fin)<1) return(E_READ);
  229.        pl+= l->mwidth;
  230.      }
  231.     else SKIPr(2*w);
  232.      
  233.     if(pc1)
  234.      { if(fread(pc1,w/2,1,fin)<1) return(E_READ);
  235.        pc1+= c1->mwidth;
  236.      }
  237.     else SKIPr(w/2);
  238.      
  239.     if(pc2)
  240.      { if(fread(pc2,w/2,1,fin)<1) return(E_READ);
  241.        pc2+= c2->mwidth;
  242.      }
  243.     else SKIPr(w/2);
  244.  
  245.  
  246.    }
  247. #ifdef DEBUG_EXTRA
  248. fprintf(stderr,"R-Position %x\n",ftell(fin));
  249. #endif
  250.   return E_NONE;
  251.  }
  252.  
  253.  
  254. void interpolate(p)
  255.   implane *p;
  256.  {dim w,h,x,y,yi;
  257.   uBYTE *optr,*nptr,*uptr;
  258.  
  259.   melde("interpolate\n");
  260.   if ((!p) || (!p->im)) error(E_INTERN);
  261.  
  262.   w=p->iwidth;
  263.   h=p->iheight;
  264.  
  265.   if(p->mwidth  < 2*w ) error(E_INTERN);
  266.   if(p->mheight < 2*h ) error(E_INTERN);
  267.  
  268.  
  269.   p->iwidth=2*w;
  270.   p->iheight=2*h;
  271.  
  272.  
  273.   for(y=0;y<h;y++)
  274.    {yi=h-1-y;
  275.     optr=p->im+  yi*p->mwidth + (w-1);
  276.     nptr=p->im+2*yi*p->mwidth + (2*w - 2);
  277.  
  278.     nptr[0]=nptr[1]=optr[0];
  279.  
  280.     for(x=1;x<w;x++)
  281.      { optr--; nptr-=2;
  282.        nptr[0]=optr[0];
  283.        nptr[1]=(((int)optr[0])+((int)optr[1])+1)>>1;
  284.      }
  285.     }
  286.  
  287.   for(y=0;y<h-1;y++)
  288.    {optr=p->im + 2*y*p->mwidth;
  289.     nptr=optr+p->mwidth;
  290.     uptr=nptr+p->mwidth;
  291.  
  292.     for(x=0;x<w-1;x++)
  293.      {
  294.       nptr[0]=(((int)optr[0])+((int)uptr[0])+1)>>1;
  295.       nptr[1]=(((int)optr[0])+((int)optr[2])+((int)uptr[0])+((int)uptr[2])+2)>>2;
  296.       nptr+=2; optr+=2; uptr+=2;
  297.      }
  298.     *(nptr++)=(((int)*(optr++))+((int)*(uptr++))+1)>>1;
  299.     *(nptr++)=(((int)*(optr++))+((int)*(uptr++))+1)>>1;
  300.    }
  301.  
  302.   bcopy(p->im + (2*h-2)*p->mwidth,
  303.         p->im + (2*h-1)*p->mwidth,
  304.         2*w);
  305.  
  306.  }
  307.  
  308.  
  309. struct ph1 
  310.  {char id1[8];
  311.   char ww1[14];
  312.   char id2[20];
  313.   char id3[4*16+4];
  314.   short ww2;
  315.   char id4[20];
  316.   char ww3[2*16+1];
  317.   char id5[4*16];
  318.   char idx[11*16];
  319.  } ;
  320.  
  321.  
  322.  
  323. struct pcdword
  324.  { uBYTE high,low;
  325.  };
  326.  
  327. struct pcdquad { uBYTE len,highseq,lowseq,key;};
  328. struct pcdhqt  { uBYTE entries; struct pcdquad entry[256];};
  329. struct myhqt { unsigned long seq,mask,len; uBYTE key; };
  330.  
  331.  
  332. #define E ((unsigned long) 1)
  333.  
  334.  
  335. static void readhqtsub(source,ziel,anzahl)
  336.   struct pcdhqt *source;
  337.   struct myhqt *ziel;
  338.   int *anzahl;
  339.  {int i;
  340.   struct pcdquad *sub;
  341.   struct myhqt *help;
  342.   *anzahl=(source->entries)+1;
  343.  
  344.   for(i=0;i<*anzahl;i++)
  345.    {sub = (struct pcdquad *)(((uBYTE *)source)+1+i*sizeof(*sub));
  346.     help=ziel+i;
  347.  
  348.     help->seq = (((unsigned long) sub->highseq) << 24) |(((unsigned long) sub->lowseq) << 16);
  349.     help->len = ((unsigned long) sub->len) +1;
  350.     help->key = sub->key;
  351.  
  352. #ifdef DEBUGhuff
  353.    fprintf(stderr," Anz: %d A1: %08x  A2: %08x X:%02x %02x %02x %02x Seq:  %08x   Laenge:  %d %d\n",
  354.           *anzahl,sbuffer,sub,((uBYTE *)sub)[0],((uBYTE *)sub)[1],((uBYTE *)sub)[2],((uBYTE *)sub)[3],
  355.           help->seq,help->len,sizeof(uBYTE));
  356. #endif
  357.  
  358.     if(help->len > 16) error(E_HUFF);
  359.  
  360.     help->mask = ~ ( (E << (32-help->len)) -1); 
  361.  
  362.   }
  363. #ifdef DEBUG_EXTRA
  364.   for(i=0;i<*anzahl;i++)
  365.    {help=ziel+i;
  366.     fprintf(stderr,"H: %3d  %08lx & %08lx (%2d) = %02x = %5d  %8x\n",
  367.         i, help->seq,help->mask,help->len,help->key,(signed char)help->key,
  368.         help->seq & (~help->mask));
  369.    }
  370. #endif
  371.  
  372. }
  373.  
  374. static struct myhqt myhuffl[256],myhuff1[256],myhuff2[256];
  375. static int          myhufflenl=0,myhufflen1=0,myhufflen2=0;
  376.  
  377. void readhqt(w,h,n, NeXT_fin)
  378.   dim w,h;
  379.   int n;
  380.   FILE *NeXT_fin;
  381.  {
  382.   uBYTE *ptr;
  383.  
  384.   melde("readhqt\n");
  385.   if(READBUF_NeXT < 1) error(E_READ);
  386.   ptr = sbuffer;
  387.  
  388.   readhqtsub((struct pcdhqt *)ptr,myhuffl,&myhufflenl);
  389.  
  390.   if(n<2) return;
  391.   ptr+= 1 + 4* myhufflenl;
  392.   readhqtsub((struct pcdhqt *)ptr,myhuff1,&myhufflen1);
  393.  
  394.   if(n<3) return;
  395.   ptr+= 1 + 4* myhufflen1;
  396.   readhqtsub((struct pcdhqt *)ptr,myhuff2,&myhufflen2);
  397.  
  398. }
  399.  
  400.  
  401.  
  402.  
  403.  
  404. void decode(w,h,f,f1,f2, autosync, NeXT_fin)
  405.   dim w,h;
  406.   implane *f,*f1,*f2;
  407.   int autosync;
  408.   FILE *NeXT_fin;
  409.  {int i,htlen,sum;
  410.   unsigned long sreg,maxwidth;
  411.   unsigned int inh,n,zeile,segment,ident;
  412.   struct myhqt *htptr,*hp;
  413.  
  414.   uBYTE *nptr;
  415.   uBYTE *lptr;
  416.  
  417.   melde("decode\n");
  418. #define nextbuf  {  nptr=sbuffer;  if(READBUF_NeXT < 1) error(E_READ); }
  419. #define checkbuf { if (nptr >= sbuffer + sizeof(sbuffer)) nextbuf; }
  420. #define shiftout(n){ sreg<<=n; inh-=n; \
  421.                      while (inh<=24) \
  422.                       {checkbuf; \
  423.                        sreg |= ((unsigned long)(*(nptr++)))<<(24-inh);\
  424.                        inh+=8;\
  425.                       }\
  426.                     }  
  427.  
  428.  
  429.   if((!f) || (!f->im)) error(E_INTERN);
  430.   if((f->iheight < h) || (f->iwidth<w)) error(E_INTERN);
  431.  
  432.   htlen=sreg=maxwidth=0;
  433.   htptr=0;
  434.   nextbuf;
  435.   inh=32;
  436.   lptr=0;
  437.   shiftout(16);
  438.   shiftout(16);
  439.  
  440.   n=0;
  441.   for(;;)
  442.    {
  443.     if((sreg & 0xffffff00) == 0xfffffe00)
  444.      {shiftout(24);
  445.       ident=sreg>>16;
  446.       shiftout(16);
  447.  
  448.       zeile=(ident>>1) & 0x1fff;
  449.       segment=ident>>14;
  450.  
  451. #ifdef DEBUG_EXTRA
  452.       fprintf(stderr,"Ident %4x Zeile:  %6d  Segment %3d Pixels bisher: %d\n",
  453.           ident,zeile,segment,n);
  454. #endif
  455.       if(lptr && (n!=maxwidth)) error(E_SEQ1);
  456.       n=0;
  457.  
  458.  
  459.       if(zeile==h) return;
  460.       if(zeile > h) error(E_SEQ2);
  461.  
  462.       switch(segment)
  463.        {
  464.         case 0: if(!f) error(E_SEQ7);
  465.                 lptr=f->im + zeile*f->mwidth;
  466.                 maxwidth=f->iwidth;
  467.                 htlen=myhufflenl;
  468.                 htptr=myhuffl;
  469.                 break;
  470.  
  471.         case 2: if(!f1) error(E_SEQ7);
  472.                 lptr=f1->im + (zeile>>1)*f1->mwidth;
  473.                 maxwidth=f1->iwidth;
  474.                 htlen=myhufflen1;
  475.                 htptr=myhuff1;
  476.                 break;
  477.  
  478.         case 3: if(!f2) error(E_SEQ7);
  479.                 lptr=f2->im + (zeile>>1)*f2->mwidth;
  480.                 maxwidth=f2->iwidth;
  481.                 htlen=myhufflen2;
  482.                 htptr=myhuff2;
  483.                 break;
  484.  
  485.         default:error(E_SEQ3);
  486.     }
  487.      }
  488.     else
  489.      {
  490. /*      if((!lptr) || (n>maxwidth)) error(E_SEQ4);*/
  491.       if(!lptr)      error(E_SEQ6);
  492.       if(n>maxwidth) error(E_SEQ4);
  493.       for(i=0,hp=htptr;(i<htlen) && ((sreg & hp->mask)!= hp->seq); i++,hp++);
  494.       if(i>=htlen) error(E_SEQ5);
  495.  
  496.       sum=((int)(*lptr)) + ((char)hp->key);
  497.       NORM(sum);
  498.       *(lptr++) = sum;
  499.  
  500.       n++; 
  501.       shiftout(hp->len);
  502.  
  503.      }
  504.  
  505.    }
  506.  
  507.  
  508.  
  509.  }
  510.  
  511.