home *** CD-ROM | disk | FTP | other *** search
/ Amiga ISO Collection / AmigaUtilCD1.iso / CDRom / PHOTOC12.LZX / src / photocdaga / tools.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-10-18  |  23.2 KB  |  918 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.  
  12. /* NOTE: don't use this file for compiling hpcdtoppm, it is heavily */
  13. /* modified by me (Günther Röhrich)                                 */
  14.  
  15. #include "hpcdtoppm.h"
  16.  
  17.  
  18.  
  19. #define cro(p,d) {if(p) {p->im+=d*p->mwidth; p->iheight-=d;}}
  20. #define cru(p,d) {if(p) {p->iheight-=d;}}
  21. #define crl(p,d) {if(p) {p->im+=d; p->iwidth-=d;}}
  22. #define crr(p,d) {if(p) {p->iwidth-=d;}}
  23.  
  24.  
  25. void cropit(sizeinfo *si,implane *l,implane *c1,implane *c2)
  26.  {dim x,y,s,w,h;
  27.   sINT nl,nr,no,nu;
  28.  
  29.   uBYTE *ptr;
  30.  
  31.   melde("crop\n");
  32.  
  33.   if(si->imvlen || si->imhlen) error(E_INTERN);
  34.   w=si->rdhlen;
  35.   h=si->rdvlen;
  36.  
  37.   if((!l) || (l->iwidth != w) || (l->iheight != h)) error(E_INTERN);
  38.   
  39.   if(!monochrome)
  40.    {if((!c1) || (c1->iwidth != w) || (c1->iheight != h)) error(E_INTERN);
  41.     if((!c2) || (c2->iwidth != w) || (c2->iheight != h)) error(E_INTERN);
  42.    }
  43.  
  44.  
  45.   for(y=0,no=0;y<h;y++,no++)
  46.    {for(x=0,ptr=(l->im)+y*(l->mwidth); x<w && (*ptr)<MAX_BLACK ;x++,ptr++);
  47.     if(x<w) break;
  48.    }
  49.   cro(l ,no);
  50.   cro(c1,no);
  51.   cro(c2,no);
  52.   h-=no;
  53.  
  54.  
  55.   for(y=h-1,nu=0;y;y--,nu++)
  56.    {for(x=0,ptr=(l->im)+y*(l->mwidth); x<w && (*ptr)<MAX_BLACK ;x++,ptr++);
  57.     if(x<w) break;
  58.    }
  59.   cru(l ,nu);
  60.   cru(c1,nu);
  61.   cru(c2,nu);
  62.   h-=nu;
  63.  
  64.  
  65.   s=l->mwidth;
  66.  
  67.   for(x=0,nl=0;x<w;x++,nl++)
  68.    {for(y=0,ptr=(l->im)+x; y<h && (*ptr)<MAX_BLACK ; y++, ptr+=s);
  69.     if(y<h) break;
  70.    }
  71.   crl(l ,nl);
  72.   crl(c1,nl);
  73.   crl(c2,nl);
  74.   w-=nl;
  75.   
  76.  
  77.   for(x=w-1,nr=0;x;x--,nr++)
  78.    {for(y=0,ptr=(l->im)+x; y<h && (*ptr)<MAX_BLACK ; y++, ptr+=s);
  79.     if(y<h) break;
  80.    }
  81.   crr(l ,nr);
  82.   crr(c1,nr);
  83.   crr(c2,nr);
  84.   w-=nr;
  85.   
  86.   if (do_melde) 
  87.    {
  88.     if (no || nu || nr || nl )
  89.       fprintf(stderr,"Cut off %d top, %d bottom, %d left, %d right,  new size is %dx%d\n",
  90.               no,nu,nl,nr,w,h);
  91.     else
  92.       fprintf(stderr,"Nothing cut off\n");
  93.    }
  94.  
  95.   si->imvlen=h;
  96.   si->imhlen=w;
  97.  }
  98.  
  99.  
  100. void shrink(sizeinfo *si,implane *l,implane *c1,implane *c2)
  101.  {dim w,h;
  102.  
  103.   melde("shrink\n");
  104.  
  105.   w=si->rdhlen;
  106.   h=si->rdvlen;
  107.  
  108.   if((!l) || (l->iwidth != w) || (l->iheight != h)) error(E_INTERN);
  109.   
  110.   if(!monochrome)
  111.    {if((!c1) || (c1->iwidth != w) || (c1->iheight != h)) error(E_INTERN);
  112.     if((!c2) || (c2->iwidth != w) || (c2->iheight != h)) error(E_INTERN);
  113.    }
  114.  
  115.   if((!si->imvlen) && (!si->imhlen))  /* no subrectangle given */
  116.    {si->imvlen=si->rdvlen;
  117.     si->imhlen=si->rdhlen;
  118.     return;
  119.    }
  120.  
  121.   if (si->imvlen>h || si->imvlen<1 )       error(E_INTERN);
  122.   if (si->imvoff> si->rdvlen - si->imvlen) error(E_INTERN);
  123.  
  124.   if (si->imhlen>w || si->imhlen<1 ) error(E_INTERN);
  125.   if (si->imhoff> si->rdhlen - si->imhlen) error(E_INTERN);
  126.  
  127.   cro(l ,si->imvoff);
  128.   cro(c1,si->imvoff);
  129.   cro(c2,si->imvoff);
  130.  
  131.   cru(l ,si->rdvlen - si->imvoff - si->imvlen);
  132.   cru(c1,si->rdvlen - si->imvoff - si->imvlen);
  133.   cru(c2,si->rdvlen - si->imvoff - si->imvlen);
  134.   
  135.   crl(l ,si->imhoff);
  136.   crl(c1,si->imhoff);
  137.   crl(c2,si->imhoff);
  138.  
  139.   crr(l ,si->rdhlen - si->imhoff - si->imhlen);
  140.   crr(c1,si->rdhlen - si->imhoff - si->imhlen);
  141.   crr(c2,si->rdhlen - si->imhoff - si->imhlen);
  142.   
  143.  
  144.  }
  145.  
  146.  
  147.  
  148. void halve(implane *p)
  149.  {dim w,h,x,y;
  150.   uBYTE *optr,*nptr;
  151.  
  152.   melde("halve\n");
  153.   if ((!p) || (!p->im)) error(E_INTERN);
  154.  
  155.   w=p->iwidth/=2;      
  156.   h=p->iheight/=2;     
  157.  
  158.  
  159.   for(y=0;y<h;y++)
  160.    {
  161.     nptr=(p->im) +   y*(p->mwidth);
  162.     optr=(p->im) + 2*y*(p->mwidth);
  163.  
  164.     for(x=0;x<w;x++,nptr++,optr+=2)
  165.      { *nptr = *optr;
  166.      }
  167.  
  168.    }
  169.  
  170.  }
  171.  
  172.  
  173.  
  174.  
  175. void planealloc(implane *p, dim width, dim height)
  176. {
  177.   melde("planealloc\n");
  178.  
  179.   p->iwidth=p->iheight=0;
  180.   p->mwidth=width;
  181.   p->mheight=height;
  182.  
  183.   p->mp = ( p->im = ( uBYTE * ) malloc  (width*height*sizeof(uBYTE)) );
  184.   if(!(p->im)) error(E_MEM);
  185. }
  186.  
  187.  
  188. enum ERRORS readplain(sizeinfo *si,int fak,implane *l,implane *c1,implane *c2)
  189.  {dim i,w,h,hoff,hlen,voff,vlen;
  190.   uBYTE *pl=0,*pc1=0,*pc2=0;
  191.  
  192.   melde("readplain\n");
  193.  
  194. #ifdef DEBUG
  195.   fprintf(stderr,"readplain %d %d %d %d %d %d %d\n",fak,si->w,si->h,si->rdhoff,si->rdhlen,si->rdvoff,si->rdvlen);
  196. #endif
  197.  
  198.   if(fak >= 0)
  199.    {w   =si->w     *fak;
  200.     h   =si->h     *fak;
  201.     hoff=si->rdhoff*fak;  if(hoff & 1 ) error(E_INTERN);  /* Must be all even */
  202.     hlen=si->rdhlen*fak;  if(hlen & 1 ) error(E_INTERN);
  203.     voff=si->rdvoff*fak;  if(voff & 1 ) error(E_INTERN);
  204.     vlen=si->rdvlen*fak;  if(vlen & 1 ) error(E_INTERN);
  205.    }
  206.   else
  207.    {fak = -fak;
  208.     w   =si->w     /fak;
  209.     h   =si->h     /fak;
  210.     hoff=si->rdhoff/fak;  if(hoff & 1 ) error(E_INTERN);  /* Must be all even */
  211.     hlen=si->rdhlen/fak;  if(hlen & 1 ) error(E_INTERN);
  212.     voff=si->rdvoff/fak;  if(voff & 1 ) error(E_INTERN);
  213.     vlen=si->rdvlen/fak;  if(vlen & 1 ) error(E_INTERN);
  214.    }
  215.  
  216.  
  217.     
  218.   if(l)
  219.    { if ((l->mwidth<hlen) || (l->mheight<vlen) || (!l->im)) error(E_INTERN);
  220.      l->iwidth=hlen;
  221.      l->iheight=vlen;
  222.      pl=l->im;
  223.    }
  224.  
  225.   if(c1)
  226.    { if ((c1->mwidth<(hlen>>1)) || (c1->mheight<(vlen>>1)) || (!c1->im)) error(E_INTERN);
  227.      c1->iwidth=hlen>>1;
  228.      c1->iheight=vlen>>1;
  229.      pc1=c1->im;
  230.    }
  231.  
  232.   if(c2)
  233.    { if ((c2->mwidth<(hlen>>1)) || (c2->mheight<(vlen>>1)) || (!c2->im)) error(E_INTERN);
  234.      c2->iwidth=hlen>>1;
  235.      c2->iheight=vlen>>1;
  236.      pc2=c2->im;
  237.    }
  238.  
  239.   if(voff) SKIPr(w*3*(voff>>1));
  240.  
  241.   for(i=0;i<vlen>>1;i++)
  242.    {
  243.     if(pl)
  244.      { if(hlen==w)
  245.         {if(READ(pl,w)<1) return(E_READ);
  246.          pl+= l->mwidth;
  247.  
  248.          if(READ(pl,w)<1) return(E_READ);
  249.          pl+= l->mwidth;
  250.         }
  251.        else
  252.         {SKIPr(hoff);
  253.  
  254.          if(READ(pl,hlen)<1) return(E_READ);
  255.          pl+= l->mwidth;
  256.          
  257.          SKIPr(w-hlen);    /* w - hlen - hoff + hoff */ 
  258.  
  259.          if(READ(pl,hlen)<1) return(E_READ);
  260.          pl+= l->mwidth;
  261.  
  262.          SKIPr(w-hoff-hlen);         
  263.         }
  264.      }
  265.     else SKIPr(2*w);
  266.      
  267.     if(pc1)
  268.      {
  269.        if(hlen==w)
  270.         {
  271.          if(READ(pc1,w>>1)<1) return(E_READ);
  272.          pc1+= c1->mwidth;
  273.         }
  274.        else
  275.         {SKIPr((hoff)>>1);
  276.          if(READ(pc1,hlen>>1)<1) return(E_READ);
  277.          pc1+= c1->mwidth;
  278.          SKIPr((w-hoff-hlen)>>1);
  279.         }
  280.      }
  281.     else SKIPr(w>>1);
  282.      
  283.     if(pc2)
  284.      {
  285.        if(hlen==w)
  286.         {
  287.          if(READ(pc2,w>>1)<1) return(E_READ);
  288.          pc2+= c2->mwidth;
  289.         }
  290.        else
  291.         {SKIPr((hoff)>>1);
  292.          if(READ(pc2,hlen>>1)<1) return(E_READ);
  293.          pc2+= c2->mwidth;
  294.          SKIPr((w-hoff-hlen)>>1);
  295.         }
  296.      }
  297.     else SKIPr(w>>1);
  298.  
  299.  
  300.    }
  301.   RPRINT;
  302.   return E_NONE;
  303.  }
  304.  
  305. void interpolate(implane *p)
  306.  {dim w,h,x,y,yi;
  307.   uBYTE *optr,*nptr,*uptr;
  308.  
  309.   melde("interpolate\n");
  310.   if ((!p) || (!p->im)) error(E_INTERN);
  311.  
  312.   w=p->iwidth;
  313.   h=p->iheight;
  314.  
  315.   if(p->mwidth  < 2*w ) error(E_INTERN);
  316.   if(p->mheight < 2*h ) error(E_INTERN);
  317.  
  318.  
  319.   p->iwidth=2*w;
  320.   p->iheight=2*h;
  321.  
  322.  
  323.   for(y=0;y<h;y++)
  324.    {yi=h-1-y;
  325.     optr=p->im+  yi*p->mwidth + (w-1);
  326.     nptr=p->im+2*yi*p->mwidth + (2*w - 2);
  327.  
  328.     nptr[0]=nptr[1]=optr[0];
  329.  
  330.     for(x=1;x<w;x++)
  331.      { optr--; nptr-=2;
  332.        nptr[0]=optr[0];
  333.        nptr[1]=(((sINT)optr[0])+((sINT)optr[1])+1)>>1;
  334.      }
  335.     }
  336.  
  337.   for(y=0;y<h-1;y++)
  338.    {optr=p->im + 2*y*p->mwidth;
  339.     nptr=optr+p->mwidth;
  340.     uptr=nptr+p->mwidth;
  341.  
  342.     for(x=0;x<w-1;x++)
  343.      {
  344.       nptr[0]=(((sINT)optr[0])+((sINT)uptr[0])+1)>>1;
  345.       nptr[1]=(((sINT)optr[0])+((sINT)optr[2])+((sINT)uptr[0])+((sINT)uptr[2])+2)>>2;
  346.       nptr+=2; optr+=2; uptr+=2;
  347.      }
  348.     *(nptr++)=(((sINT)*(optr++))+((sINT)*(uptr++))+1)>>1;
  349.     *(nptr++)=(((sINT)*(optr++))+((sINT)*(uptr++))+1)>>1;
  350.    }
  351.  
  352.  
  353.   optr=p->im + (2*h-2)*p->mwidth;
  354.   nptr=p->im + (2*h-1)*p->mwidth;
  355.   for(x=0;x<w;x++)
  356.    { *(nptr++) = *(optr++);  *(nptr++) = *(optr++); }
  357.  
  358.  }
  359.  
  360.  
  361. void eerror(enum ERRORS e,char *file,int line)
  362.  {
  363.   
  364.   switch(e)
  365.    {case E_NONE:   return;
  366.     case E_IMP:    fprintf(stderr,"Sorry, Not yet implemented. [%s:%d]\n",file,line); break;
  367.     case E_READ:   fprintf(stderr,"Error while reading.\n"); break;
  368.     case E_WRITE:  fprintf(stderr,"Error while writing.\n"); break;
  369.     case E_INTERN: fprintf(stderr,"Internal error. [%s:%d]\n",file,line); break; 
  370.     case E_MEM:    fprintf(stderr,"Not enough memory !\n"); break;
  371.     case E_DISPLAY: fprintf(stderr, "Could not open display!\n"); break;
  372.     case E_MAPFILE: fprintf(stderr, "Error while reading mapfile.\n"); break;
  373.     case E_PICNUM:  fprintf(stderr, "Wrong picture number.\n"); break;
  374.     case E_ABORT:  close_all();
  375.                    exit(0);
  376.  
  377.     case E_ARG:    fprintf(stderr,"Usage: PhotoCDAGA PhotoCD-file [ppm-file] switches\n"
  378.            "switches: -b name  search for mapfile with basename\n" 
  379.            "          -x       overskip mode (tries to improve color quality)\n"
  380.            "          -s       apply simple sharpness-operator on the Luma-channel\n"
  381.            "          -c       try to cut off the black frame\n"
  382.            "          -n       don't rotate\n"
  383.            "          -r       rotate clockwise for portraits\n"
  384.            "          -l       rotate counter-clockwise for portraits\n"
  385.            "          -h       rotate twice, turn on head\n"
  386.            "          -m       show decoding steps\n"
  387.            "          -c-      correct darker\n"
  388.            "          -c+      correct brighter\n"
  389.            "          -pgm     create grayscale pgm output\n"
  390.            "          -ppm     create ppm output\n"
  391.            "          -gray    use grayscale display\n"
  392.            "          -vga     use VGA screenmode\n"
  393.            "          -orig    use original system drawing functions\n"
  394.            "          -0 n     show overview starting with picture n\n"
  395.            "          -1       extract 128x192 (Base/16)\n"
  396.            "          -2       extract 256x384 (Base/4)\n"
  397.            "          -3       extract 512x768 (Base), default\n"); break;
  398.    }
  399.   close_all();
  400.   exit(10);
  401. }
  402.  
  403.  
  404.  
  405.  
  406. static void flip_corr(dim w,dim h,uBYTE **ptr,sdim *ystep,sdim *xstep)
  407. {
  408.  if(flvert) 
  409.  {
  410.    (*ptr) += (h-1)* (*ystep);
  411.    (*ystep) = -(*ystep);
  412.  }
  413.  
  414.  if(flhori)
  415.  {
  416.    (*ptr) += (w-1)* (*xstep);
  417.    (*xstep) = -(*xstep);
  418.  }
  419. }
  420.  
  421.  
  422.  
  423.  
  424. static void call_1plane(OUT1PL proc, FILE *fout,
  425.                         dim w,    dim h,uBYTE * ptr,
  426.                         sdim zeil, sdim pix) 
  427.  {
  428.   flip_corr(w,h,&ptr,&zeil,&pix);
  429.   (*proc)(fout,w,h,ptr,zeil,pix);
  430.  }
  431.  
  432.  
  433.  
  434. static void do_1plane(OUT1PL proc, FILE *fout,
  435.                       dim w,dim h,implane *g,enum TURNS t)
  436.  {
  437.    switch(t)
  438.     {case T_NONE: call_1plane(proc,fout,w,h,g->im,g->mwidth,1);
  439.                   break;
  440.      case T_RIGHT:call_1plane(proc,fout,h,w,g->im + g->mwidth * ( g->iheight - 1) , 1 , -(g->mwidth));
  441.                   break;
  442.      case T_LEFT: call_1plane(proc,fout,h,w,g->im + g->iwidth - 1 , -1 , (g->mwidth));
  443.                   break; 
  444.      case T_HEAD: call_1plane(proc,fout,w,h,g->im + g->iwidth - 1 + g->mwidth * ( g->iheight - 1)  , -(g->mwidth) , -1);
  445.                   break;     
  446.      default:error(E_INTERN);
  447.     }
  448.  
  449.  }
  450.  
  451.  
  452.  
  453.  
  454.  
  455.  
  456.  
  457. static void call_3plane(OUT3PL proc, FILE *fout,  dim w,dim h, 
  458.                         uBYTE *rptr,sdim rzeil,sdim rpix,  
  459.                         uBYTE *gptr,sdim gzeil,sdim gpix,  
  460.                         uBYTE *bptr,sdim bzeil,sdim bpix) 
  461.  {
  462.   flip_corr(w,h,&rptr,&rzeil,&rpix);
  463.   flip_corr(w,h,&gptr,&gzeil,&gpix);
  464.   flip_corr(w,h,&bptr,&bzeil,&bpix);
  465.  
  466.   (*proc)(fout,w,h,rptr,rzeil,rpix,gptr,gzeil,gpix,bptr,bzeil,bpix );
  467.  }
  468.  
  469.  
  470. static void do_3plane(OUT3PL proc,FILE *fout,dim w,dim h,
  471.                       implane *r,implane *g,implane *b,
  472.                       enum TURNS t)
  473.  {
  474.    switch(t)
  475.     {case T_NONE: call_3plane(proc,fout,w,h,r->im,r->mwidth,1,
  476.                                             g->im,g->mwidth,1,
  477.                                             b->im,b->mwidth,1);
  478.                   break;     
  479.      case T_RIGHT:call_3plane(proc,fout,h,w,r->im + r->mwidth * ( r->iheight - 1) , 1 , -(r->mwidth),
  480.                                             g->im + g->mwidth * ( g->iheight - 1) , 1 , -(g->mwidth),
  481.                                             b->im + b->mwidth * ( b->iheight - 1) , 1 , -(b->mwidth));
  482.                   break;     
  483.      case T_LEFT: call_3plane(proc,fout,h,w,r->im + r->iwidth - 1 , -1 , (r->mwidth),
  484.                                             g->im + g->iwidth - 1 , -1 , (g->mwidth),
  485.                                             b->im + b->iwidth - 1 , -1 , (b->mwidth));
  486.                   break;           
  487.      case T_HEAD: call_3plane(proc,fout,w,h,r->im + r->iwidth - 1 + r->mwidth * ( r->iheight - 1)  , -(r->mwidth) , -1,
  488.                                             g->im + g->iwidth - 1 + g->mwidth * ( g->iheight - 1)  , -(g->mwidth) , -1,
  489.                                             b->im + b->iwidth - 1 + b->mwidth * ( b->iheight - 1)  , -(b->mwidth) , -1);
  490.                   break;     
  491.      default:error(E_INTERN);
  492.     }
  493.  
  494.  }
  495.  
  496.  
  497.  
  498. static sINT testbegin(void)
  499.  {sINT i,j;
  500.   for(i=j=0;i<32;i++)
  501.     if(sbuffer[i]==0xff) j++;
  502.  
  503.   return (j>30);
  504.   
  505.  }
  506.  
  507.  
  508. sINT Skip4Base(void)
  509.  {sINT cd_offset,cd_offhelp;
  510.   
  511.   cd_offset = L_Head + L_Base16 + L_Base4 + L_Base ;
  512.   SEEK(cd_offset+3);          
  513.   EREADBUF;    
  514.   cd_offhelp=((((sINT)sbuffer[510])<<8)|sbuffer[511]) + 1;
  515.  
  516.   cd_offset+=cd_offhelp;
  517.  
  518.   SEEK(cd_offset);
  519.   EREADBUF;
  520.   while(!testbegin())
  521.    {cd_offset++;
  522.     EREADBUF;
  523.    }
  524.   return cd_offset;
  525.  }
  526.  
  527.  
  528.  
  529. void writepicture(FILE *fout, sizeinfo *si, 
  530.                   implane *r,implane *g,implane *b,
  531.                   enum TURNS t)
  532.  {dim w,h;
  533.  
  534.   w=si->imhlen;
  535.   h=si->imvlen;
  536.  
  537.   melde("writepicture\n");
  538.      if((!r) || (r->iwidth != w ) || (r->iheight != h) || (!r->im)) error(E_INTERN);
  539.   
  540.   if(!monochrome)
  541.    {
  542.      if((!g) || (g->iwidth != w ) || (g->iheight != h) || (!g->im)) error(E_INTERN);
  543.      if((!b) || (b->iwidth != w ) || (b->iheight != h) || (!b->im)) error(E_INTERN);
  544.    }
  545.  
  546.   switch(outfor)
  547.    {
  548.     case O_PPM:    do_3plane(write_ppm     ,fout,w,h,r,g,b,t); break;
  549.     case O_DCOLOR: do_3plane(write_dcolor  ,fout,w,h,r,g,b,t); break;
  550.     case O_DOVER_COLOR:  do_3plane(write_dover_color  ,fout,w,h,r,g,b,t); break;
  551.  
  552.     case O_PGM:   do_1plane(write_pgm     ,fout,w,h,r,t);     break;
  553.     case O_DGRAY: do_1plane(write_dgray     ,fout,w,h,r,t);     break;
  554.     case O_DOVER_GRAY: do_1plane(write_dover_gray     ,fout,w,h,r,t);     break;
  555.  
  556.     default: error(E_INTERN);
  557.    }
  558.  
  559.  
  560.  }
  561.  
  562.  
  563.  
  564. struct ph1 
  565.  {char  id1[8];
  566.   uBYTE ww1[14];
  567.   char  id2[20];
  568.   char  id3[4*16+4];
  569.   short ww2;
  570.   char  id4[20];
  571.   uBYTE ww3[2*16+1];
  572.   char  id5[4*16];
  573.   uBYTE idx[11*16];
  574.  } ;
  575.  
  576.  
  577. void druckeid(void)
  578. {struct ph1 *d;
  579.  char ss[100];
  580.  
  581.  d=(struct ph1 *)sbuffer;
  582.  
  583. #define dr(feld,kennung)   \
  584.      strncpy(ss,feld,sizeof(feld));\
  585.      ss[sizeof(feld)]=0;\
  586.      fprintf(stderr,"%s: %s \n",kennung,ss);
  587.  
  588.  
  589. dr(d->id1,"Id1")
  590. dr(d->id2,"Id2")
  591. dr(d->id3,"Id3")
  592. dr(d->id4,"Id4")
  593. dr(d->id5,"Id5")
  594.  
  595. #undef dr 
  596.  
  597. }
  598.  
  599. struct pcdquad { uBYTE len,highseq,lowseq,key;};
  600. struct pcdhqt  { uBYTE entries; struct pcdquad entry[256];};
  601. struct myhqt   { uINT seq,mask,len; uBYTE key; };
  602.  
  603. static struct myhqt myhuff0[256],myhuff1[256],myhuff2[256];
  604. static sINT          myhufflen0=0,myhufflen1=0,myhufflen2=0;
  605.  
  606.  
  607.  
  608. static void readhqtsub(struct pcdhqt *quelle,struct myhqt *ziel,sINT *anzahl)
  609. #define E ((uINT) 1)
  610.  {sINT i;
  611.   struct pcdquad *sub;
  612.   struct myhqt *help;
  613.   *anzahl=(quelle->entries)+1;
  614.  
  615.   for(i=0;i<*anzahl;i++)
  616.    {sub = (struct pcdquad *)(((uBYTE *)quelle)+1+i*sizeof(*sub));
  617.     help=ziel+i;
  618.  
  619.     help->seq = (((uINT) sub->highseq) << 24) |(((uINT) sub->lowseq) << 16);
  620.     help->len = ((uINT) sub->len) +1;
  621.     help->key = sub->key;
  622.  
  623. #ifdef DEBUGhuff
  624.    fprintf(stderr," Anz: %d A1: %08x  A2: %08x X:%02x %02x %02x %02x Seq:  %08x   Laenge:  %d %d\n",
  625.           *anzahl,(uINT)sbuffer,(uINT)sub,
  626.           ((uBYTE *)sub)[0],((uBYTE *)sub)[1],((uBYTE *)sub)[2],((uBYTE *)sub)[3],
  627.           help->seq,help->len,sizeof(uBYTE));
  628. #endif
  629.  
  630.     if(help->len > 16) error(E_HUFF);
  631.  
  632.     help->mask = ~ ( (E << (32-help->len)) -1); 
  633.  
  634.   }
  635. #ifdef DEBUG
  636.   for(i=0;i<*anzahl;i++)
  637.    {help=ziel+i;
  638.     fprintf(stderr,"H: %3d  %08lx & %08lx (%2d) = %02x = %5d  %8x\n",
  639.         i, help->seq,help->mask,help->len,help->key,(sBYTE)help->key,
  640.         help->seq & (~help->mask));
  641.    }
  642. #endif
  643.  
  644. #undef E
  645. }
  646.  
  647.  
  648.  
  649.  
  650. void readhqt(sINT n)
  651.  {
  652.   uBYTE *ptr;
  653.  
  654.   melde("readhqt\n");
  655.   EREADBUF;
  656.   ptr = sbuffer;
  657.  
  658.   readhqtsub((struct pcdhqt *)ptr,myhuff0,&myhufflen0);
  659.  
  660.   if(n<2) return;
  661.   ptr+= 1 + 4* myhufflen0;
  662.   readhqtsub((struct pcdhqt *)ptr,myhuff1,&myhufflen1);
  663.  
  664.   if(n<3) return;
  665.   ptr+= 1 + 4* myhufflen1;
  666.   readhqtsub((struct pcdhqt *)ptr,myhuff2,&myhufflen2);
  667.  
  668. }
  669.  
  670.  
  671.  
  672. #ifdef FASTHUFF
  673.  
  674. static struct myhqt *HTAB0[0x10000],*HTAB1[0x10000],*HTAB2[0x10000];
  675.  
  676. static void inithuff(sINT hlen,struct myhqt *ptr,struct myhqt *TAB[])
  677.  {sINT i,n;
  678.   sINT seq,len;
  679.   struct myhqt *help;
  680.  
  681.   for(i=0;i<0x10000;i++) TAB[i]=0;
  682.  
  683.   for(n=0;n<hlen;n++)
  684.    {help=ptr+n;
  685.     seq=(help->seq)>>16;
  686.     len=help->len;
  687.  
  688.     for(i=0;i<(1<<(16-len));i++)
  689.       TAB[seq | i] = help;
  690.    }
  691.  }
  692. #endif
  693.  
  694.  
  695.  
  696. static char *pn[]={"Luma Channel","Chroma1 Channel","Chroma2 Channel"};
  697.  
  698.  
  699. void decode(sizeinfo *si,int fak,implane *f,implane *f1,implane *f2,sINT autosync)
  700.  {dim w,h,hoff,hlen,hende,voff,vlen,vende,anfang,ende;
  701.   sINT htlen,sum,do_inform,part;
  702.   uINT sreg,maxwidth;
  703.   uINT inh,n,zeile,segment,ident;
  704.   struct myhqt *hp;
  705.  
  706.   uBYTE *nptr;
  707.   uBYTE *lptr;
  708.  
  709. #define nextbuf  {  nptr=sbuffer; if(READBUF<1) { if(!do_rep) error(E_READ); \
  710.                                                   fprintf(stderr,"Read error\n"); \
  711.                                                   return; } }
  712. #define checkbuf { if (nptr >= sbuffer + sizeof(sbuffer)) nextbuf; }
  713.  
  714. #ifdef U_TOO_LONG
  715. #define shiftreg(n) sreg = (sreg<< n ) & 0xffffffff;
  716. #else
  717. #define shiftreg(n) sreg<<=n;
  718. #endif
  719.  
  720. #define shiftout(n){ shiftreg(n); inh-=n; \
  721.                      while (inh<=24) \
  722.                       {checkbuf; \
  723.                        sreg |= ((uINT)(*(nptr++)))<<(24-inh);\
  724.                        inh+=8;\
  725.                       }\
  726.                     }  
  727. #define issync     ((sreg & 0xffffff00) == 0xfffffe00) 
  728. #define brutesync  ((sreg & 0x00fff000) == 0x00fff000) 
  729. #define seeksync { while (!brutesync) shiftout(8); while (!issync) shiftout(1);}
  730.  
  731. #ifdef FASTHUFF
  732.   struct myhqt **HTAB;
  733.   HTAB=0;
  734.   inithuff(myhufflen0,myhuff0,HTAB0);
  735.   inithuff(myhufflen1,myhuff1,HTAB1);
  736.   inithuff(myhufflen2,myhuff2,HTAB2);
  737. #define SETHUFF0 HTAB=HTAB0;
  738. #define SETHUFF1 HTAB=HTAB1;
  739. #define SETHUFF2 HTAB=HTAB2;
  740. #define FINDHUFF(x) {x=HTAB[sreg>>16];}
  741.  
  742. #else
  743.  
  744.   sINT i;
  745.   struct myhqt *htptr;
  746.   htptr=0;
  747. #define SETHUFF0 { htlen=myhufflen0 ; htptr = myhuff0 ; }
  748. #define SETHUFF1 { htlen=myhufflen1 ; htptr = myhuff1 ; }
  749. #define SETHUFF2 { htlen=myhufflen2 ; htptr = myhuff2 ; }
  750. #define FINDHUFF(x)  {for(i=0, x=htptr;(i<htlen) && ((sreg & x ->mask)!= x->seq); i++,x++); \
  751.                       if(i>=htlen) x=0;}
  752. #endif
  753.  
  754.   melde("decode\n");
  755.   anfang=ende=0;
  756.  
  757.   if(fak >= 0)
  758.    {w   =si->w     *fak;
  759.     h   =si->h     *fak;
  760.     hoff=si->rdhoff*fak;  if(hoff & 1 ) error(E_INTERN);  /* Must be all even */
  761.     hlen=si->rdhlen*fak;  if(hlen & 1 ) error(E_INTERN); hende=hlen+hoff;
  762.     voff=si->rdvoff*fak;  if(voff & 1 ) error(E_INTERN);
  763.     vlen=si->rdvlen*fak;  if(vlen & 1 ) error(E_INTERN); vende=vlen+voff;
  764.    }
  765.   else
  766.    {fak = -fak;
  767.     w   =si->w     /fak;
  768.     h   =si->h     /fak;
  769.     hoff=si->rdhoff/fak;  if(hoff & 1 ) error(E_INTERN);  /* Must be all even */
  770.     hlen=si->rdhlen/fak;  if(hlen & 1 ) error(E_INTERN); hende=hlen+hoff; 
  771.     voff=si->rdvoff/fak;  if(voff & 1 ) error(E_INTERN);
  772.     vlen=si->rdvlen/fak;  if(vlen & 1 ) error(E_INTERN); vende=vlen+voff;
  773.    }
  774.  
  775.  
  776.   if( f  && ((! f->im) || ( f->iheight != vlen  ) ||  (f->iwidth != hlen  ))) error(E_INTERN);
  777.   if( f1 && ((!f1->im) || (f1->iheight != vlen/2) || (f1->iwidth != hlen/2))) error(E_INTERN);
  778.   if( f2 && ((!f2->im) || (f2->iheight != vlen/2) || (f2->iwidth != hlen/2))) error(E_INTERN);
  779.  
  780.   htlen=sreg=maxwidth=0;
  781.   zeile=0;
  782.   nextbuf;
  783.   inh=32;
  784.   lptr=0;
  785.   part=do_inform=0;
  786.   shiftout(16);
  787.   shiftout(16);
  788.  
  789.   if(autosync) seeksync;
  790.   
  791.   if(!issync)
  792.    { if(!do_rep) error(E_SEQ6);
  793.      else 
  794.       {fprintf(stderr,"Image does not start with synchron mark, seeking...\n");
  795.        seeksync;
  796.        do_inform=1;
  797.       }
  798.    }
  799.  
  800.   n=0;
  801.  
  802.   for(;;)
  803.    {
  804.     if (issync)
  805.      {shiftout(24);
  806.       ident=sreg>>16;
  807.       shiftout(16);
  808.  
  809.       zeile=(ident>>1) & 0x1fff;
  810.       segment=ident>>14;
  811.       if(do_inform) {fprintf(stderr,"Synchron mark found Line %d\n",zeile);do_inform=0;}
  812. #ifdef DEBUG
  813.       fprintf(stderr,"Id %4x Zeile: %6d Seg %3d Pix bisher: %5d  Position: %8lx+%5lx=%8x\n",
  814.           ident,zeile,segment,n,bufpos,nptr-sbuffer,bufpos+nptr-sbuffer);
  815. #endif
  816.  
  817.  
  818.       if(lptr && (n!=maxwidth)) 
  819.        {if(!do_rep)error(E_SEQ1);
  820.         else fprintf(stderr,"Line %d in %s : wrong length of last line (%d)\n",zeile,pn[part],n);
  821.        }
  822.       n=0;
  823.  
  824.       if(zeile==h) {RPRINT; return; }
  825.       if(zeile >h) 
  826.        { if(!do_rep) error(E_SEQ2);
  827.          else 
  828.           {fprintf(stderr,"Wrong line number %d, ignoring line\n",zeile);
  829.            seeksync;
  830.            n=maxwidth;
  831.            do_inform=1;
  832.           }
  833.        }    
  834.       else switch(segment)
  835.        {
  836.         case 1: if(!do_rep) error(E_SEQ3);
  837.                 fprintf(stderr,"Abnormal line tag in %d, interpreting as Luma tag\n",zeile);
  838.         case 0: maxwidth=w;
  839.                 if((!f) && autosync) {seeksync; n=maxwidth; break;}
  840.                 if(!f) error(E_SEQ7);
  841.                 if((zeile<voff) || (zeile >= vende)) {seeksync; n=maxwidth; break;}
  842.                 anfang=hoff; ende=hende;
  843.                 lptr=f->im + (zeile-voff)*f->mwidth;
  844.                 SETHUFF0;
  845.                 part=0;
  846.                 break;
  847.  
  848.         case 2: maxwidth=w>>1;
  849.                 if(!f1) return;
  850.                 /*if((!f1) && autosync) {seeksync; break;}*/
  851.                 if((zeile<voff) || (zeile >= vende)) {seeksync; n=maxwidth; break;}
  852.                 anfang=hoff>>1; ende=hende>>1;
  853.                 lptr=f1->im + ((zeile-voff)>>1)*f1->mwidth;
  854.                 SETHUFF1;
  855.                 part=1;
  856.                 break;
  857.  
  858.         case 3: maxwidth=w>>1;
  859.                 if(!f2) return;
  860.                 /*if((!f2) && autosync) {seeksync; break;}*/
  861.                 if((zeile<voff) || (zeile >= vende)) {seeksync; n=maxwidth; break;}
  862.                 anfang=hoff>>1; ende=hende>>1;
  863.                 lptr=f2->im + ((zeile-voff)>>1)*f2->mwidth;
  864.                 SETHUFF2;
  865.                 part=2;
  866.                 break;
  867.  
  868.         default:error(E_SEQ3);
  869.     }
  870.      }
  871.     else
  872.      {
  873.       if(!lptr)      error(E_SEQ6);
  874.  
  875.       if(n>maxwidth) 
  876.         {
  877. #ifdef DEBUG
  878.          fprintf(stderr,"Register: %08lx Pos: %08lx\n",sreg,bufpos+nptr-sbuffer);
  879. #endif
  880.          if (!do_rep) error(E_SEQ4);
  881.          else { fprintf(stderr,"Missing synchron mark in %s line %d\n",pn[part],zeile);
  882.                 seeksync;
  883.                 do_inform=1;
  884.                 n=maxwidth;
  885.               }
  886.        }
  887.       else
  888.        {FINDHUFF(hp);
  889.         if(!hp)
  890.          { if(!do_rep) error(E_SEQ5);
  891.            fprintf(stderr,"Unable to decode, ignoring rest of line\n");
  892.            seeksync;
  893.            n=maxwidth;
  894.            do_inform=1;
  895.          }
  896.         else
  897.          {if((n>= anfang) && (n<ende))
  898.            {sum=((sINT)(*lptr)) + ((sBYTE)hp->key);
  899.             NORM(sum);
  900.             *(lptr++) = sum;
  901.            }
  902.  
  903.           n++; 
  904.           shiftout(hp->len);
  905.          }
  906.        }
  907.      }
  908.  
  909.    }
  910.  
  911.  
  912. #undef nextbuf  
  913. #undef checkbuf 
  914. #undef shiftout
  915. #undef issync
  916. #undef seeksync
  917.  
  918.  }