home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / netpbma.zip / ppm / hpcdtoppm.c < prev    next >
C/C++ Source or Header  |  1996-11-10  |  38KB  |  1,455 lines

  1. /* hpcdtoppm (Hadmut's pcdtoppm) v0.3
  2. *  Copyright (c) 1992 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. /* define OWN_WRITE either here or by compiler-option if you don't want to use
  13.    the pbmplus-routines for writing */
  14. #define xOWN_WRITE
  15.  
  16.  
  17. /* define DEBUG for some debugging informations, just remove the x from xDEBUG */
  18. #define xDEBUG
  19.  
  20. /* define MELDUNG if you want to see what is happening and what takes time,
  21.    just remove the x from xMeldung */
  22. #define xMELDUNG
  23.  
  24.  
  25.  
  26.  
  27.  
  28. #ifndef OWN_WRITE
  29.  
  30. #include "ppm.h"
  31.  
  32. #else
  33.  
  34. /* If the own routines are used, this is the size of the buffer in bytes.
  35.    You can shrink if needed. */
  36. #define own_BUsize 50000
  37. #include <stdio.h>
  38.  
  39.  
  40. /* The header for the ppm-files */
  41. #define PPM_Header "P6\n%d %d\n255\n"
  42.  
  43.  
  44. #endif
  45.  
  46.  
  47. /*
  48. ** Important: sBYTE must be a signed byte type !!!
  49. **
  50. */
  51.  
  52. #ifndef sBYTE
  53. #ifndef VMS
  54. typedef   signed char sBYTE;
  55. #else
  56. typedef   char sBYTE;
  57. #endif
  58. #endif
  59.  
  60. typedef unsigned char uBYTE;
  61. typedef unsigned long dim;
  62.  
  63. #define BaseW ((dim)768)
  64. #define BaseH ((dim)512)
  65.  
  66. #define SECSIZE 0x800
  67.  
  68.  
  69.  
  70. #define SeHead   2
  71. #define L_Head   (1+SeHead)
  72.  
  73. #define SeBase16 18
  74. #define L_Base16 (1+SeBase16)
  75.  
  76. #define SeBase4  72
  77. #define L_Base4  (1+SeBase4)
  78.  
  79. #define SeBase   288
  80. #define L_Base   (1+SeBase)
  81.  
  82.  
  83.  
  84.  
  85.  
  86.  
  87. enum ERRORS { E_NONE,E_READ,E_WRITE,E_INTERN,E_ARG,E_OPT,E_MEM,E_HUFF,
  88.              E_SEQ,E_SEQ1,E_SEQ2,E_SEQ3,E_SEQ4,E_SEQ5,E_SEQ6,E_SEQ7,E_POS,E_IMP,E_OVSKIP,
  89.              E_TAUTO,E_TCANT };
  90.  
  91. enum TURNS  { T_NONE,T_RIGHT,T_LEFT,T_AUTO };
  92.  
  93. enum SIZES  { S_UNSPEC,S_Base16,S_Base4,S_Base,S_4Base,S_16Base,S_Over };
  94.  
  95. /* Default taken when no size parameter given */
  96. #define S_DEFAULT S_Base16
  97.  
  98.  
  99.  
  100.  
  101.  
  102. struct _implane
  103.  {dim  mwidth,mheight,
  104.        iwidth,iheight;
  105.   uBYTE *im;
  106.  };
  107. typedef struct _implane implane;
  108.  
  109. #define nullplane ((implane *) 0)
  110.  
  111. struct pcdquad { uBYTE len,highseq,lowseq,key;};
  112. struct pcdhqt  { uBYTE entries; struct pcdquad entry[256];};
  113. struct myhqt { unsigned long seq,mask,len; uBYTE key; };
  114.  
  115.  
  116. static void error ARGS((enum ERRORS e));
  117. static void planealloc ARGS((implane *p, dim width, dim height));
  118. static enum ERRORS readplain ARGS((dim w, dim h, implane *l, implane *c1, implane *c2));
  119. static void interpolate ARGS((implane *p));
  120. static void halve ARGS((implane *p));
  121. static void ycctorgb ARGS((dim w, dim h, implane *l, implane *c1, implane *c2));
  122. static void writepicture ARGS((dim w, dim h, implane *r, implane *g, implane *b, enum TURNS t));
  123. static void druckeid ARGS((void));
  124. static void clear ARGS((implane *l, int n));
  125. static long Skip4Base ARGS((void));
  126. static void readhqt ARGS((dim w, dim h, int n));
  127. static void decode ARGS((dim w, dim h, implane *f, implane *f1, implane *f2, int autosync));
  128. static void sharpit ARGS((implane *l));
  129. static void readhqtsub ARGS((struct pcdhqt *source, struct myhqt *ziel, int *anzahl));
  130. static int testbegin ARGS((void));
  131.  
  132. static FILE *fin=0,*fout=0;
  133. static char *pcdname=0,*ppmname=0;
  134. static char nbuf[100];
  135. static uBYTE sbuffer[SECSIZE];
  136. static int do_sharp,keep_ycc;
  137.  
  138.  
  139.  
  140.  
  141. /* Using preprocessor for inline-procs */
  142. #ifdef DEBUG
  143.  
  144. static long bufpos;
  145.  
  146. #define SEEK(x) { if (fseek(fin,((x) * SECSIZE),0)) error(E_READ);\
  147.                   fprintf(stderr,"S-Position %x\n",ftell(fin)); }
  148. #define RPRINT  {fprintf(stderr,"R-Position %x\n",ftell(fin));}
  149.  
  150. #define READBUF   (bufpos=ftell(fin),fread(sbuffer,sizeof(sbuffer),1,fin))
  151.  
  152.  
  153. #else
  154.  
  155. #define SEEK(x) { if (fseek(fin,((x) * SECSIZE),0)) error(E_READ);}
  156. #define RPRINT
  157. #define READBUF   fread(sbuffer,sizeof(sbuffer),1,fin)
  158.  
  159. #endif
  160.  
  161.  
  162. #ifdef MELDUNG
  163. #define melde(x) fprintf(stderr,x)
  164. #else
  165. #define melde(x)
  166. #endif
  167.  
  168.  
  169.  
  170.  
  171.  
  172.  
  173.  
  174.  
  175. #define EREADBUF {if(READBUF < 1) error(E_READ);}
  176.  
  177. #define SKIP(n)  { if (fseek(fin,(n),1)) error(E_READ);}
  178. #define SKIPr(n) { if (fseek(fin,(n),1)) return(E_READ);}
  179.  
  180.  
  181. #define xTRIF(x,u,o,a,b,c) ((x)<(u)? (a) : ( (x)>(o)?(c):(b)  ))
  182. #define xNORM(x) x=TRIF(x,0,255,0,x,255)
  183. #define NORM(x) { if(x<0) x=0; else if (x>255) x=255;}
  184.  
  185.  
  186.  
  187.  
  188.  
  189. static void error(e)
  190.   enum ERRORS e;
  191.  {
  192.  
  193.   switch(e)
  194.    {case E_NONE:   return;
  195.     case E_IMP:    fprintf(stderr,"Sorry, Not yet implemented.\n"); break;
  196.     case E_READ:   fprintf(stderr,"Error while reading.\n"); break;
  197.     case E_WRITE:  fprintf(stderr,"Error while writing.\n"); break;
  198.     case E_INTERN: fprintf(stderr,"Internal error.\n"); break;
  199.     case E_ARG:    fprintf(stderr,"Error in Arguments !\n\n");
  200.                    fprintf(stderr,"Usage: hpcdtoppm [options] pcd-file [ppm-file]\n\n");
  201.                    fprintf(stderr,"Opts:\n");
  202.                    fprintf(stderr,"     -x Overskip mode (tries to improve color quality.)\n");
  203.                    fprintf(stderr,"     -i Give some (buggy) informations from fileheader\n");
  204.                    fprintf(stderr,"     -s Apply simple sharpness-operator on the Luma-channel\n");
  205.                    fprintf(stderr,"     -d Show differential picture only \n\n");
  206.                    fprintf(stderr,"     -r Rotate clockwise for portraits\n");
  207.                    fprintf(stderr,"     -l Rotate counter-clockwise for portraits\n");
  208.                    fprintf(stderr,"     -a Try to find out orientation automatically.\n");
  209.                    fprintf(stderr,"        (Experimentally, please report if it doesn't work.)\n\n");
  210.                    fprintf(stderr,"     -ycc suppress ycc to rgb conversion \n");
  211.                    fprintf(stderr,"        (Experimentally, doesn't have deeper sense)\n\n");
  212.                    fprintf(stderr,"     -0 Extract thumbnails from Overview file\n");
  213.                    fprintf(stderr,"     -1 Extract  128x192  from Image file\n");
  214.                    fprintf(stderr,"     -2 Extract  256x384  from Image file\n");
  215.                    fprintf(stderr,"     -3 Extract  512x768  from Image file\n");
  216.                    fprintf(stderr,"     -4 Extract 1024x1536 from Image file\n");
  217.                    fprintf(stderr,"     -5 Extract 2048x3072 from Image file\n");
  218.                    fprintf(stderr,"\n");
  219.                    break;
  220.     case E_OPT:    fprintf(stderr,"These Options are not allowed together.\n");break;
  221.     case E_MEM:    fprintf(stderr,"Not enough memory !\n"); break;
  222.     case E_HUFF:   fprintf(stderr,"Error in Huffman-Code-Table\n"); break;
  223.     case E_SEQ:    fprintf(stderr,"Error in Huffman-Sequence\n"); break;
  224.     case E_SEQ1:   fprintf(stderr,"Error1 in Huffman-Sequence\n"); break;
  225.     case E_SEQ2:   fprintf(stderr,"Error2 in Huffman-Sequence\n"); break;
  226.     case E_SEQ3:   fprintf(stderr,"Error3 in Huffman-Sequence\n"); break;
  227.     case E_SEQ4:   fprintf(stderr,"Error4 in Huffman-Sequence\n"); break;
  228.     case E_SEQ5:   fprintf(stderr,"Error5 in Huffman-Sequence\n"); break;
  229.     case E_SEQ6:   fprintf(stderr,"Error6 in Huffman-Sequence\n"); break;
  230.     case E_SEQ7:   fprintf(stderr,"Error7 in Huffman-Sequence\n"); break;
  231.     case E_POS:    fprintf(stderr,"Error in file-position\n"); break;
  232.     case E_OVSKIP: fprintf(stderr,"Can't read this resolution in overskip-mode\n"); break;
  233.     case E_TAUTO:  fprintf(stderr,"Can't determine the orientation in overview mode\n");break;
  234.     case E_TCANT:  fprintf(stderr,"Sorry, can't determine orientation for this file.\n");
  235.                    fprintf(stderr,"Please give orientation parameters. \n");break;
  236.     default:       fprintf(stderr,"Unknown error %d ???\n",e);break;
  237.    }
  238.   if(fin) fclose(fin);
  239.   if(fout && ppmname) fclose(fout);
  240.   exit(9);
  241.  }
  242.  
  243.  
  244.  
  245.  
  246.  
  247.  
  248.  
  249.  
  250.  
  251. static void planealloc(p,width,height)
  252.   implane *p;
  253.   dim width,height;
  254.  {
  255.   p->iwidth=p->iheight=0;
  256.   p->mwidth=width;
  257.   p->mheight=height;
  258.  
  259.   p->im = ( uBYTE * ) malloc  (width*height*sizeof(uBYTE));
  260.   if(!(p->im)) error(E_MEM);
  261.  }
  262.  
  263.  
  264.  
  265.  
  266.  
  267. int
  268. main(argc,argv)
  269.   int argc;
  270.   char **argv;
  271. #define ASKIP { argc--; argv ++;}
  272. {int bildnr;
  273.  char *opt;
  274.  dim w,h;
  275.  long cd_offset,cd_offhelp;
  276.  int do_info,do_diff,do_overskip;
  277.  
  278.  enum TURNS turn=T_NONE;
  279.  enum SIZES size=S_UNSPEC;
  280.  enum ERRORS eret;
  281.  implane Luma, Chroma1,Chroma2;
  282.  
  283.  ppm_init(&argc, argv);
  284.  
  285.  do_info=do_diff=do_overskip=do_sharp=keep_ycc=0;
  286.  
  287.  ASKIP;
  288.  
  289.  while((argc>0) && **argv=='-')
  290.   {
  291.    opt= (*argv)+1;
  292.    ASKIP;
  293.  
  294.    if(!strcmp(opt,"r"))
  295.     {if (turn == T_NONE) turn=T_RIGHT;
  296.      else error(E_ARG);
  297.      continue;
  298.     }
  299.  
  300.    if(!strcmp(opt,"l"))
  301.     {if (turn == T_NONE) turn=T_LEFT;
  302.      else error(E_ARG);
  303.      continue;
  304.     }
  305.  
  306.     if(!strcmp(opt,"a"))
  307.     {if (turn == T_NONE) turn=T_AUTO;
  308.      else error(E_ARG);
  309.      continue;
  310.     }
  311.  
  312.    if(!strcmp(opt,"i"))
  313.     { if (!do_info) do_info=1;
  314.       else error(E_ARG);
  315.       continue;
  316.     }
  317.  
  318.  
  319.    if(!strcmp(opt,"d"))
  320.     { if (!do_diff) do_diff=1;
  321.       else error(E_ARG);
  322.       continue;
  323.     }
  324.  
  325.    if(!strcmp(opt,"s"))
  326.     { if (!do_sharp) do_sharp=1;
  327.       else error(E_ARG);
  328.       continue;
  329.     }
  330.  
  331.  
  332.    if(!strcmp(opt,"x"))
  333.     { if (!do_overskip) do_overskip=1;
  334.       else error(E_ARG);
  335.       continue;
  336.     }
  337.  
  338.  
  339.    if(!strcmp(opt,"ycc"))
  340.     { if (!keep_ycc) keep_ycc=1;
  341.       else error(E_ARG);
  342.       continue;
  343.     }
  344.  
  345.  
  346.  
  347.  
  348.    if((!strcmp(opt,"Base/16")) || (!strcmp(opt,"1"))  || (!strcmp(opt,"128x192")))
  349.     { if (size == S_UNSPEC) size = S_Base16;
  350.       else error(E_ARG);
  351.       continue;
  352.     }
  353.    if((!strcmp(opt,"Base/4" )) || (!strcmp(opt,"2"))  || (!strcmp(opt,"256x384")))
  354.     { if (size == S_UNSPEC) size = S_Base4;
  355.       else error(E_ARG);
  356.       continue;
  357.     }
  358.    if((!strcmp(opt,"Base"   )) || (!strcmp(opt,"3"))  || (!strcmp(opt,"512x768")))
  359.     { if (size == S_UNSPEC) size = S_Base;
  360.       else error(E_ARG);
  361.       continue;
  362.     }
  363.    if((!strcmp(opt,"4Base"  )) || (!strcmp(opt,"4"))  || (!strcmp(opt,"1024x1536")))
  364.     { if (size == S_UNSPEC) size = S_4Base;
  365.       else error(E_ARG);
  366.       continue;
  367.     }
  368.    if((!strcmp(opt,"16Base" )) || (!strcmp(opt,"5"))  || (!strcmp(opt,"2048x3072")))
  369.     { if (size == S_UNSPEC) size = S_16Base;
  370.       else error(E_ARG);
  371.       continue;
  372.     }
  373.  
  374.    if((!strcmp(opt,"Overview" )) || (!strcmp(opt,"0"))  || (!strcmp(opt,"O")))
  375.     { if (size == S_UNSPEC) size = S_Over;
  376.       else error(E_ARG);
  377.       continue;
  378.     }
  379.  
  380.   fprintf(stderr,"Unknown option: -%s\n",opt);
  381.   error(E_ARG);
  382.   }
  383.  
  384.  
  385.  
  386.  
  387.   if(size==S_UNSPEC) size=S_DEFAULT;
  388.  
  389.   if(argc<1) error(E_ARG);
  390.   pcdname= *argv;
  391.   ASKIP;
  392.  
  393.   if(argc>0)
  394.    {ppmname= *argv;
  395.     ASKIP;
  396.    }
  397.  
  398.   if(argc>0) error(E_ARG);
  399.   if((size==S_Over) && (!ppmname)) error(E_ARG);
  400.   if(do_info && (size==S_Over)) error(E_OPT);
  401.   if(do_overskip && do_diff) error(E_OPT);
  402.   if(do_diff && (size != S_4Base) && (size != S_16Base)) error(E_OPT);
  403.   if(do_overskip && (size != S_Base16) && (size != S_Base4) && (size != S_Base) && (size != S_4Base) ) error(E_OVSKIP);
  404.   if((turn==T_AUTO)&&(size==S_Over)) error(E_TAUTO);
  405.  
  406.  
  407.  
  408.  
  409. #ifdef __EMX__
  410.   if(!(fin=fopen(pcdname,"rb"))) error(E_READ);
  411. #else
  412.   if(!(fin=fopen(pcdname,"r"))) error(E_READ);
  413. #endif
  414.  
  415.   if(do_info || (turn==T_AUTO))
  416.    { SEEK(1);
  417.      EREADBUF;
  418.    }
  419.  
  420.   if(turn==T_AUTO)
  421.    {
  422.     switch(sbuffer[0xe02 & 0x7ff]&0x03)
  423.      {case 0x00: turn=T_NONE;  break;
  424.       case 0x01: turn=T_LEFT;  break;
  425.       case 0x03: turn=T_RIGHT; break;
  426.       default: error(E_TCANT);
  427.      }
  428.    }
  429.  
  430.   if(do_info) druckeid();
  431.  
  432.  
  433.  
  434.  
  435.  
  436.   switch(size)
  437.    {
  438.     case S_Base16: w=BaseW/4;
  439.                    h=BaseH/4;
  440.                    planealloc(&Luma   ,w,h);
  441.                    planealloc(&Chroma1,w,h);
  442.                    planealloc(&Chroma2,w,h);
  443.  
  444.                    if(!do_overskip)
  445.                      { SEEK(L_Head+1);
  446.                        error(readplain(w,h,&Luma,&Chroma1,&Chroma2));
  447.                        interpolate(&Chroma1);
  448.                        interpolate(&Chroma2);
  449.                      }
  450.                    else
  451.                      { SEEK(L_Head+1);
  452.                        error(readplain(w,h,&Luma,nullplane,nullplane));
  453.                        SEEK(L_Head+L_Base16+1);
  454.                        error(readplain(2*w,2*h,nullplane,&Chroma1,&Chroma2));
  455.                      }
  456.  
  457.  
  458.                    ycctorgb(w,h,&Luma,&Chroma1,&Chroma2);
  459.                    /* Now Luma holds red, Chroma1 hold green, Chroma2 holds blue */
  460.  
  461.                    if(!ppmname) fout=stdout;
  462.                    else
  463. #ifdef __EMX__
  464.                     {if (!(fout=fopen(ppmname,"wb"))) error(E_WRITE);
  465. #else
  466.                     {if (!(fout=fopen(ppmname,"w"))) error(E_WRITE);
  467. #endif
  468.                     }
  469.                    writepicture(w,h,&Luma,&Chroma1,&Chroma2,turn);
  470.  
  471.                    break;
  472.  
  473.     case S_Base4:  w=BaseW/2;
  474.                    h=BaseH/2;
  475.                    planealloc(&Luma   ,w,h);
  476.                    planealloc(&Chroma1,w,h);
  477.                    planealloc(&Chroma2,w,h);
  478.  
  479.  
  480.  
  481.                   if(!do_overskip)
  482.                      { SEEK(L_Head+L_Base16+1);
  483.                        error(readplain(w,h,&Luma,&Chroma1,&Chroma2));
  484.                        interpolate(&Chroma1);
  485.                        interpolate(&Chroma2);
  486.                      }
  487.                    else
  488.                      { SEEK(L_Head+L_Base16+1);
  489.                        error(readplain(w,h,&Luma,nullplane,nullplane));
  490.                        SEEK(L_Head+L_Base16+L_Base4+1);
  491.                        error(readplain(2*w,2*h,nullplane,&Chroma1,&Chroma2));
  492.                      }
  493.                    ycctorgb(w,h,&Luma,&Chroma1,&Chroma2);
  494.                    /* Now Luma holds red, Chroma1 hold green, Chroma2 holds blue */
  495.  
  496.                    if(!ppmname) fout=stdout;
  497.                    else
  498. #ifdef __EMX__
  499.                     {if (!(fout=fopen(ppmname,"wb"))) error(E_WRITE);
  500. #else
  501.                     {if (!(fout=fopen(ppmname,"w"))) error(E_WRITE);
  502. #endif
  503.                     }
  504.                    writepicture(w,h,&Luma,&Chroma1,&Chroma2,turn);
  505.  
  506.                    break;
  507.  
  508.     case S_Base:   w=BaseW;
  509.                    h=BaseH;
  510.  
  511.                    if(!do_overskip)
  512.                      { planealloc(&Luma   ,w,h);
  513.                        planealloc(&Chroma1,w,h);
  514.                        planealloc(&Chroma2,w,h);
  515.                        SEEK(L_Head+L_Base16+L_Base4+1);
  516.                        error(readplain(w,h,&Luma,&Chroma1,&Chroma2));
  517.                        interpolate(&Chroma1);
  518.                        interpolate(&Chroma2);
  519.                      }
  520.                    else
  521.                      { planealloc(&Luma   ,  w,  h);
  522.                        planealloc(&Chroma1,2*w,2*h);
  523.                        planealloc(&Chroma2,2*w,2*h);
  524.                        SEEK(L_Head+L_Base16+L_Base4+1);
  525.                        error(readplain(w,h,&Luma,&Chroma1,&Chroma2));
  526.                        interpolate(&Chroma1);
  527.                        interpolate(&Chroma2);
  528.                        interpolate(&Chroma1);
  529.                        interpolate(&Chroma2);
  530.  
  531.                        cd_offset=Skip4Base();
  532.                        SEEK(cd_offset+10);          EREADBUF;    cd_offhelp=(((long)sbuffer[2])<<8)|sbuffer[3];
  533.                        SEEK(cd_offset+12);          readhqt(w,h,3);
  534.                        SEEK(cd_offset+cd_offhelp);  decode(4*w,4*h,nullplane,&Chroma1,&Chroma2,1);
  535.  
  536.                        halve(&Chroma1);
  537.                        halve(&Chroma2);
  538.                      }
  539.                    ycctorgb(w,h,&Luma,&Chroma1,&Chroma2);
  540.                    /* Now Luma holds red, Chroma1 hold green, Chroma2 holds blue */
  541.  
  542.                    if(!ppmname) fout=stdout;
  543.                    else
  544. #ifdef __EMX__
  545.                     {if (!(fout=fopen(ppmname,"wb"))) error(E_WRITE);
  546. #else
  547.                     {if (!(fout=fopen(ppmname,"w"))) error(E_WRITE);
  548. #endif
  549.                     }
  550.                    writepicture(w,h,&Luma,&Chroma1,&Chroma2,turn);
  551.  
  552.                    break;
  553.  
  554.     case S_4Base:  w=BaseW*2;
  555.                    h=BaseH*2;
  556.                    planealloc(&Luma,w,h);
  557.                    planealloc(&Chroma1,w,h);
  558.                    planealloc(&Chroma2,w,h);
  559.  
  560.                   if(!do_overskip)
  561.                      {SEEK(L_Head+L_Base16+L_Base4+1);
  562.                       error(readplain(w/2,h/2,&Luma,&Chroma1,&Chroma2));
  563.                       interpolate(&Luma);
  564.                       interpolate(&Chroma1);
  565.                       interpolate(&Chroma1);
  566.                       interpolate(&Chroma2);
  567.                       interpolate(&Chroma2);
  568.  
  569.                       if(do_diff) {clear(&Luma,128);clear(&Chroma1,156);clear(&Chroma2,137);}
  570.  
  571.                       cd_offset = L_Head + L_Base16 + L_Base4 + L_Base ;
  572.                       SEEK(cd_offset + 4);     readhqt(w,h,1);
  573.                       SEEK(cd_offset + 5);     decode(w,h,&Luma,nullplane,nullplane,0);
  574.                      }
  575.                    else
  576.                      {SEEK(L_Head+L_Base16+L_Base4+1);
  577.                       error(readplain(w/2,h/2,&Luma,&Chroma1,&Chroma2));
  578.                       interpolate(&Luma);
  579.                       interpolate(&Chroma1);
  580.                       interpolate(&Chroma1);
  581.                       interpolate(&Chroma2);
  582.                       interpolate(&Chroma2);
  583.  
  584.                       cd_offset = L_Head + L_Base16 + L_Base4 + L_Base ;
  585.                       SEEK(cd_offset + 4);     readhqt(w,h,1);
  586.                       SEEK(cd_offset + 5);     decode(w,h,&Luma,nullplane,nullplane,0);
  587.  
  588.                       cd_offset=ftell(fin);if(cd_offset % SECSIZE) error(E_POS);cd_offset/=SECSIZE;
  589.                       SEEK(cd_offset+10);          EREADBUF;    cd_offhelp=(((long)sbuffer[2])<<8)|sbuffer[3];
  590.                       SEEK(cd_offset+12);          readhqt(w,h,3);
  591.                       SEEK(cd_offset+cd_offhelp);  decode(2*w,2*h,nullplane,&Chroma1,&Chroma2,1);
  592.  
  593.                      }
  594.                    ycctorgb(w,h,&Luma,&Chroma1,&Chroma2);
  595.                    /* Now Luma holds red, Chroma1 hold green, Chroma2 holds blue */
  596.  
  597.                    if(!ppmname) fout=stdout;
  598.                    else
  599. #ifdef __EMX__
  600.                     {if (!(fout=fopen(ppmname,"wb"))) error(E_WRITE);
  601. #else
  602.                     {if (!(fout=fopen(ppmname,"w"))) error(E_WRITE);
  603. #endif
  604.                     }
  605.                    writepicture(w,h,&Luma,&Chroma1,&Chroma2,turn);
  606.  
  607.                    break;
  608.  
  609.     case S_16Base: w=BaseW*4;
  610.                    h=BaseH*4;
  611.                    planealloc(&Luma,w,h);
  612.                    planealloc(&Chroma1,w,h);
  613.                    planealloc(&Chroma2,w,h);
  614.  
  615.                    SEEK(L_Head+L_Base16+L_Base4+1);
  616.                    error(readplain(w/4,h/4,&Luma,&Chroma1,&Chroma2));
  617.                    interpolate(&Luma);
  618.                    interpolate(&Chroma1);
  619.                    interpolate(&Chroma1);
  620.                    interpolate(&Chroma2);
  621.                    interpolate(&Chroma2);
  622.  
  623.                    cd_offset = L_Head + L_Base16 + L_Base4 + L_Base ;
  624.                    SEEK(cd_offset + 4);       readhqt(w/2,h/2,1);
  625.                    SEEK(cd_offset + 5);       decode(w/2,h/2,&Luma,nullplane,nullplane,0);
  626.                    interpolate(&Luma);
  627.  
  628.                    if(do_diff) {clear(&Luma,128);clear(&Chroma1,156);clear(&Chroma2,137);}
  629.  
  630.                    cd_offset=ftell(fin);if(cd_offset % SECSIZE) error(E_POS);cd_offset/=SECSIZE;
  631.  
  632.                    SEEK(cd_offset+12);        readhqt(w,h,3);
  633.                    SEEK(cd_offset+14);        decode(w,h,&Luma,&Chroma1,&Chroma2,0);
  634.  
  635.                    interpolate(&Chroma1);
  636.                    interpolate(&Chroma2);
  637.  
  638.                    ycctorgb(w,h,&Luma,&Chroma1,&Chroma2);
  639.                    /* Now Luma holds red, Chroma1 hold green, Chroma2 holds blue */
  640.  
  641.                    if(!ppmname) fout=stdout;
  642.                    else
  643. #ifdef __EMX__
  644.                     {if (!(fout=fopen(ppmname,"wb"))) error(E_WRITE);
  645. #else
  646.                     {if (!(fout=fopen(ppmname,"w"))) error(E_WRITE);
  647. #endif
  648.                     }
  649.                    writepicture(w,h,&Luma,&Chroma1,&Chroma2,turn);
  650.  
  651.                    break;
  652.  
  653.     case S_Over:   w=BaseW/4;
  654.                    h=BaseH/4;
  655.  
  656.                    planealloc(&Luma   ,w,h);
  657.                    planealloc(&Chroma1,w,h);
  658.                    planealloc(&Chroma2,w,h);
  659.  
  660.                    for(bildnr=0;!feof(fin);bildnr++)
  661.                     {
  662.                        SEEK(5+SeBase16*bildnr);
  663.  
  664.                        eret=readplain(w,h,&Luma,&Chroma1,&Chroma2);
  665.                        if(eret==E_READ) break;
  666.                        error(eret);
  667.  
  668.                        interpolate(&Chroma1);
  669.                        interpolate(&Chroma2);
  670.  
  671.                        ycctorgb(w,h,&Luma,&Chroma1,&Chroma2);
  672.                        /* Now Luma holds red, Chroma1 hold green, Chroma2 holds blue */
  673.  
  674.                        sprintf(nbuf,"%s%04d",ppmname,bildnr+1);
  675. #ifdef __EMX__
  676.                        if (!(fout=fopen(nbuf,"wb"))) error(E_WRITE);
  677. #else
  678.                        if (!(fout=fopen(nbuf,"w"))) error(E_WRITE);
  679. #endif
  680.                        writepicture(w,h,&Luma,&Chroma1,&Chroma2,turn);
  681.                      }
  682.                    break;
  683.  
  684.      default: error(E_INTERN);
  685.    }
  686.  
  687.  
  688.  
  689.  
  690. exit(0);
  691.  
  692.  
  693.  
  694. }
  695. #undef ASKIP
  696.  
  697.  
  698.  
  699.  
  700.  
  701.  
  702. static enum ERRORS readplain(w,h,l,c1,c2)
  703.   dim w,h;
  704.   implane *l,*c1,*c2;
  705.  {dim i;
  706.   uBYTE *pl=0,*pc1=0,*pc2=0;
  707.   melde("readplain\n");
  708.  
  709.   if(l)
  710.    { if ((l->mwidth<w) || (l->mheight<h) || (!l->im)) error(E_INTERN);
  711.      l->iwidth=w;
  712.      l->iheight=h;
  713.      pl=l->im;
  714.    }
  715.  
  716.   if(c1)
  717.    { if ((c1->mwidth<w/2) || (c1->mheight<h/2) || (!c1->im)) error(E_INTERN);
  718.      c1->iwidth=w/2;
  719.      c1->iheight=h/2;
  720.      pc1=c1->im;
  721.    }
  722.  
  723.   if(c2)
  724.    { if ((c2->mwidth<w/2) || (c2->mheight<h/2) || (!c2->im)) error(E_INTERN);
  725.      c2->iwidth=w/2;
  726.      c2->iheight=h/2;
  727.      pc2=c2->im;
  728.    }
  729.  
  730.   for(i=0;i<h/2;i++)
  731.    {
  732.     if(pl)
  733.      {
  734.        if(fread(pl,w,1,fin)<1) return(E_READ);
  735.        pl+= l->mwidth;
  736.  
  737.        if(fread(pl,w,1,fin)<1) return(E_READ);
  738.        pl+= l->mwidth;
  739.      }
  740.     else SKIPr(2*w);
  741.  
  742.     if(pc1)
  743.      { if(fread(pc1,w/2,1,fin)<1) return(E_READ);
  744.        pc1+= c1->mwidth;
  745.      }
  746.     else SKIPr(w/2);
  747.  
  748.     if(pc2)
  749.      { if(fread(pc2,w/2,1,fin)<1) return(E_READ);
  750.        pc2+= c2->mwidth;
  751.      }
  752.     else SKIPr(w/2);
  753.  
  754.  
  755.    }
  756.   RPRINT;
  757.   return E_NONE;
  758.  }
  759.  
  760.  
  761.  
  762.  
  763.  
  764.  
  765.  
  766.  
  767.  
  768.  
  769.  
  770. static void interpolate(p)
  771.   implane *p;
  772.  {dim w,h,x,y,yi;
  773.   uBYTE *optr,*nptr,*uptr;
  774.  
  775.   melde("interpolate\n");
  776.   if ((!p) || (!p->im)) error(E_INTERN);
  777.  
  778.   w=p->iwidth;
  779.   h=p->iheight;
  780.  
  781.   if(p->mwidth  < 2*w ) error(E_INTERN);
  782.   if(p->mheight < 2*h ) error(E_INTERN);
  783.  
  784.  
  785.   p->iwidth=2*w;
  786.   p->iheight=2*h;
  787.  
  788.  
  789.   for(y=0;y<h;y++)
  790.    {yi=h-1-y;
  791.     optr=p->im+  yi*p->mwidth + (w-1);
  792.     nptr=p->im+2*yi*p->mwidth + (2*w - 2);
  793.  
  794.     nptr[0]=nptr[1]=optr[0];
  795.  
  796.     for(x=1;x<w;x++)
  797.      { optr--; nptr-=2;
  798.        nptr[0]=optr[0];
  799.        nptr[1]=(((int)optr[0])+((int)optr[1])+1)>>1;
  800.      }
  801.     }
  802.  
  803.   for(y=0;y<h-1;y++)
  804.    {optr=p->im + 2*y*p->mwidth;
  805.     nptr=optr+p->mwidth;
  806.     uptr=nptr+p->mwidth;
  807.  
  808.     for(x=0;x<w-1;x++)
  809.      {
  810.       nptr[0]=(((int)optr[0])+((int)uptr[0])+1)>>1;
  811.       nptr[1]=(((int)optr[0])+((int)optr[2])+((int)uptr[0])+((int)uptr[2])+2)>>2;
  812.       nptr+=2; optr+=2; uptr+=2;
  813.      }
  814.     *(nptr++)=(((int)*(optr++))+((int)*(uptr++))+1)>>1;
  815.     *(nptr++)=(((int)*(optr++))+((int)*(uptr++))+1)>>1;
  816.    }
  817.  
  818.  
  819.   optr=p->im + (2*h-2)*p->mwidth;
  820.   nptr=p->im + (2*h-1)*p->mwidth;
  821.   for(x=0;x<w;x++)
  822.    { *(nptr++) = *(optr++);  *(nptr++) = *(optr++); }
  823.  
  824.  }
  825.  
  826.  
  827.  
  828.  
  829.  
  830.  
  831.  
  832.  
  833.  
  834.  
  835. static void halve(p)
  836.   implane *p;
  837.  {dim w,h,x,y;
  838.   uBYTE *optr,*nptr;
  839.  
  840.   melde("halve\n");
  841.   if ((!p) || (!p->im)) error(E_INTERN);
  842.  
  843.   w=p->iwidth/=2;
  844.   h=p->iheight/=2;
  845.  
  846.  
  847.   for(y=0;y<h;y++)
  848.    {
  849.     nptr=(p->im) +   y*(p->mwidth);
  850.     optr=(p->im) + 2*y*(p->mwidth);
  851.  
  852.     for(x=0;x<w;x++,nptr++,optr+=2)
  853.      { *nptr = *optr;
  854.      }
  855.  
  856.    }
  857.  
  858.  }
  859.  
  860.  
  861.  
  862.  
  863.  
  864.  
  865.  
  866.  
  867.  
  868.  
  869.  
  870. #define BitShift 12
  871.  
  872. static void ycctorgb(w,h,l,c1,c2)
  873.   dim w,h;
  874.   implane *l,*c1,*c2;
  875.  {dim x,y;
  876.   uBYTE *pl,*pc1,*pc2;
  877.   long red,green,blue,i;
  878.   long L;
  879.   static int init=0;
  880.   static long XL[256],XC1[256],XC2[256],XC1g[256],XC2g[256];
  881.  
  882.   melde("ycctorgb\n");
  883.   if((!l ) || ( l->iwidth != w ) || ( l->iheight != h) || (! l->im)) error(E_INTERN);
  884.   if((!c1) || (c1->iwidth != w ) || (c1->iheight != h) || (!c1->im)) error(E_INTERN);
  885.   if((!c2) || (c2->iwidth != w ) || (c2->iheight != h) || (!c2->im)) error(E_INTERN);
  886.  
  887.   if(do_sharp) sharpit(l);
  888.   if(keep_ycc) return;
  889.  
  890.   if(!init)
  891.    {init=1;
  892.     for(i=0;i<256;i++)
  893.      {  XL[i]= 5564 * i + 2048;
  894.        XC1[i]= 9085 * i - 1417185;
  895.        XC2[i]= 7461 * i - 1022138;
  896.       XC1g[i]= 274934 - 1762 * i;
  897.       XC2g[i]= 520268 - 3798 * i;
  898.      }
  899.    }
  900.  
  901.   for(y=0;y<h;y++)
  902.    {
  903.     pl =  l->im + y *  l->mwidth;
  904.     pc1= c1->im + y * c1->mwidth;
  905.     pc2= c2->im + y * c2->mwidth;
  906.  
  907.     for(x=0;x<w;x++)
  908.      {
  909.       L = XL[*pl];
  910.       red  =(L + XC2[*pc2]               )>>BitShift;
  911.       green=(L + XC1g[*pc1] + XC2g[*pc2] )>>BitShift;
  912.       blue =(L + XC1[*pc1]               )>>BitShift;
  913.  
  914.       NORM(red);
  915.       NORM(green);
  916.       NORM(blue);
  917.  
  918.       *(pl++ )=red;
  919.       *(pc1++)=green;
  920.       *(pc2++)=blue;
  921.      }
  922.    }
  923.  }
  924. #undef BitShift
  925.  
  926.  
  927.  
  928.  
  929.  
  930.  
  931. static void writepicture(w,h,r,g,b,t)
  932.   dim w,h;
  933.   implane *r,*g,*b;
  934.   enum TURNS t;
  935.  {dim x,y;
  936.   register uBYTE *pr,*pg,*pb;
  937. #ifndef OWN_WRITE
  938.   pixel *pixrow;
  939.   register pixel* pP;
  940. #else
  941.   static uBYTE BUF[own_BUsize],*BUptr;
  942.   int   BUcount;
  943.  
  944. #define BUinit {BUcount=0;BUptr=BUF;}
  945. #define BUflush {fwrite(BUF,BUcount*3,1,fout);BUinit; }
  946. #define BUwrite(r,g,b) {if(BUcount>=own_BUsize/3) BUflush; *BUptr++ = r ; *BUptr++ = g ; *BUptr++ = b ; BUcount++;}
  947.  
  948. #endif
  949.  
  950.   melde("writepicture\n");
  951.   if((!r) || (r->iwidth != w ) || (r->iheight != h) || (!r->im)) error(E_INTERN);
  952.   if((!g) || (g->iwidth != w ) || (g->iheight != h) || (!g->im)) error(E_INTERN);
  953.   if((!b) || (b->iwidth != w ) || (b->iheight != h) || (!b->im)) error(E_INTERN);
  954.  
  955.   switch (t)
  956.    { case T_NONE:
  957. #ifndef OWN_WRITE
  958.               ppm_writeppminit(fout,w,h,(pixval) 255, 0);
  959.               pixrow = ppm_allocrow( w );
  960.               for(y=0;y<h;y++)
  961.                {
  962.                 pr= r->im + y * r->mwidth;
  963.                 pg= g->im + y * g->mwidth;
  964.                 pb= b->im + y * b->mwidth;
  965.  
  966.                 for(pP= pixrow,x=0;x<w;x++)
  967.                  {
  968.                   PPM_ASSIGN(*pP,((int)*pr),((int)*pg),((int)*pb));
  969.                   pP++;  pr++;  pg++;  pb++;
  970.                  }
  971.                 ppm_writeppmrow( fout, pixrow, w, (pixval) 255, 0 );
  972.  
  973.                }
  974.               pm_close(fout);
  975. #else
  976.               fprintf(fout,PPM_Header,w,h);
  977.               BUinit;
  978.               for(y=0;y<h;y++)
  979.                {
  980.                 pr= r->im + y * r->mwidth;
  981.                 pg= g->im + y * g->mwidth;
  982.                 pb= b->im + y * b->mwidth;
  983.  
  984.                 for(x=0;x<w;x++) BUwrite(*pr++,*pg++,*pb++);
  985.                }
  986.               BUflush;
  987.               if(ppmname) fclose(fout);
  988. #endif
  989.               break;
  990.      case T_RIGHT:
  991. #ifndef OWN_WRITE
  992.               ppm_writeppminit(fout,h,w,(pixval) 255, 0);
  993.               pixrow = ppm_allocrow( h );
  994.  
  995.               for(y=0;y<w;y++)
  996.                {
  997.                 pr= r->im + r->mwidth * ( r->iheight - 1) + y;
  998.                 pg= g->im + g->mwidth * ( g->iheight - 1) + y;
  999.                 pb= b->im + b->mwidth * ( b->iheight - 1) + y;
  1000.  
  1001.                 for(pP= pixrow,x=0;x<h;x++)
  1002.                  {
  1003.                   PPM_ASSIGN(*pP,((int)*pr),((int)*pg),((int)*pb));
  1004.                   pP++;   pr-= r->mwidth;  pg-= g->mwidth;  pb-= b->mwidth;
  1005.                  }
  1006.                 ppm_writeppmrow( fout, pixrow, h, (pixval) 255, 0 );
  1007.  
  1008.                }
  1009.               pm_close(fout);
  1010. #else
  1011.               fprintf(fout,PPM_Header,h,w);
  1012.               BUinit;
  1013.               for(y=0;y<w;y++)
  1014.                {
  1015.                 pr= r->im + r->mwidth * ( r->iheight - 1) + y;
  1016.                 pg= g->im + g->mwidth * ( g->iheight - 1) + y;
  1017.                 pb= b->im + b->mwidth * ( b->iheight - 1) + y;
  1018.  
  1019.                 for(x=0;x<h;x++)
  1020.                 {BUwrite(*pr,*pg,*pb);
  1021.                  pr-= r->mwidth;  pg-= g->mwidth;  pb-= b->mwidth;
  1022.                 }
  1023.                }
  1024.               BUflush;
  1025.               if(ppmname) fclose(fout);
  1026. #endif
  1027.               break;
  1028.  
  1029.       case T_LEFT:
  1030. #ifndef OWN_WRITE
  1031.               ppm_writeppminit(fout,h,w,(pixval) 255, 0);
  1032.               pixrow = ppm_allocrow( h );
  1033.  
  1034.               for(y=0;y<w;y++)
  1035.                {
  1036.                 pr= r->im + r->iwidth - 1 - y;
  1037.                 pg= g->im + g->iwidth - 1 - y;
  1038.                 pb= b->im + b->iwidth - 1 - y;
  1039.  
  1040.  
  1041.  
  1042.                 for(pP= pixrow,x=0;x<h;x++)
  1043.                  {
  1044.                   PPM_ASSIGN(*pP,((int)*pr),((int)*pg),((int)*pb));
  1045.                   pP++;   pr+= r->mwidth;  pg+= g->mwidth;  pb+= b->mwidth;
  1046.                  }
  1047.                 ppm_writeppmrow( fout, pixrow, h, (pixval) 255, 0 );
  1048.  
  1049.                }
  1050.               pm_close(fout);
  1051. #else
  1052.               fprintf(fout,PPM_Header,h,w);
  1053.               BUinit;
  1054.               for(y=0;y<w;y++)
  1055.                {
  1056.                 pr= r->im + r->iwidth - 1 - y;
  1057.                 pg= g->im + g->iwidth - 1 - y;
  1058.                 pb= b->im + b->iwidth - 1 - y;
  1059.  
  1060.                 for(x=0;x<h;x++)
  1061.                 {BUwrite(*pr,*pg,*pb);
  1062.                  pr+= r->mwidth;  pg+= g->mwidth;  pb+= b->mwidth;
  1063.                 }
  1064.                }
  1065.               BUflush;
  1066.               if(ppmname) fclose(fout);
  1067.  
  1068. #endif
  1069.               break;
  1070.       default: error(E_INTERN);
  1071.     }
  1072.  }
  1073.  
  1074.  
  1075.  
  1076.  
  1077.  
  1078.  
  1079.  
  1080.  
  1081.  
  1082.  
  1083.  
  1084.  
  1085.  
  1086.  
  1087.  
  1088.  
  1089.  
  1090.  
  1091.  
  1092.  
  1093. struct ph1
  1094.  {char  id1[8];
  1095.   uBYTE ww1[14];
  1096.   char  id2[20];
  1097.   char  id3[4*16+4];
  1098.   short ww2;
  1099.   char  id4[20];
  1100.   uBYTE ww3[2*16+1];
  1101.   char  id5[4*16];
  1102.   uBYTE idx[11*16];
  1103.  } ;
  1104.  
  1105.  
  1106. static void druckeid()
  1107. {int i;
  1108.  struct ph1 *d;
  1109.  char ss[100];
  1110.  
  1111.  d=(struct ph1 *)sbuffer;
  1112.  
  1113. #define dr(feld,kennung)   \
  1114.      strncpy(ss,feld,sizeof(feld));\
  1115.      ss[sizeof(feld)]=0;\
  1116.      fprintf(stderr,"%s: %s \n",kennung,ss);
  1117.  
  1118. #define db(feld) fprintf(stderr,"--%d\n",sizeof(feld)); for(i=0;i<sizeof(feld);i+=2) \
  1119.   fprintf(stderr,"%4d %6d\n",i,(signed int)((((unsigned int)feld[i])<<8)|feld[i+1]));\
  1120.   fprintf(stderr,"\n");
  1121.  
  1122. dr(d->id1,"Id1")
  1123. dr(d->id2,"Id2")
  1124. dr(d->id3,"Id3")
  1125. dr(d->id4,"Id4")
  1126. dr(d->id5,"Id5")
  1127.  
  1128. /*
  1129. db(d->ww1)
  1130. db(d->ww3)
  1131. db(d->idx)
  1132. */
  1133.  
  1134. #undef dr
  1135. #undef db
  1136.  
  1137. }
  1138.  
  1139.  
  1140.  
  1141. struct pcdword
  1142.  { uBYTE high,low;
  1143.  };
  1144.  
  1145. static int lpt[1024];
  1146.  
  1147. static void readlpt(w,h)
  1148.   dim w,h;
  1149.  {int i;
  1150.   struct pcdword *ptr;
  1151.  
  1152.   EREADBUF;
  1153.  
  1154.   ptr = (struct pcdword *)sbuffer;
  1155.  
  1156.   for(i=0;i<h/4;i++,ptr++)
  1157.    {lpt[i] = ((int)ptr->high)<<8 | ptr->low ;
  1158.    }
  1159.  
  1160.  
  1161.  
  1162.  }
  1163.  
  1164.  
  1165.  
  1166. #define E ((unsigned long) 1)
  1167.  
  1168.  
  1169. static void readhqtsub(source,ziel,anzahl)
  1170.   struct pcdhqt *source;
  1171.   struct myhqt *ziel;
  1172.   int *anzahl;
  1173.  {int i;
  1174.   struct pcdquad *sub;
  1175.   struct myhqt *help;
  1176.   *anzahl=(source->entries)+1;
  1177.  
  1178.   for(i=0;i<*anzahl;i++)
  1179.    {sub = (struct pcdquad *)(((uBYTE *)source)+1+i*sizeof(*sub));
  1180.     help=ziel+i;
  1181.  
  1182.     help->seq = (((unsigned long) sub->highseq) << 24) |(((unsigned long) sub->lowseq) << 16);
  1183.     help->len = ((unsigned long) sub->len) +1;
  1184.     help->key = sub->key;
  1185.  
  1186. #ifdef DEBUGhuff
  1187.    fprintf(stderr," Anz: %d A1: %08x  A2: %08x X:%02x %02x %02x %02x Seq:  %08x   Laenge:  %d %d\n",
  1188.           *anzahl,sbuffer,sub,((uBYTE *)sub)[0],((uBYTE *)sub)[1],((uBYTE *)sub)[2],((uBYTE *)sub)[3],
  1189.           help->seq,help->len,sizeof(uBYTE));
  1190. #endif
  1191.  
  1192.     if(help->len > 16) error(E_HUFF);
  1193.  
  1194.     help->mask = ~ ( (E << (32-help->len)) -1);
  1195.  
  1196.   }
  1197. #ifdef DEBUG
  1198.   for(i=0;i<*anzahl;i++)
  1199.    {help=ziel+i;
  1200.     fprintf(stderr,"H: %3d  %08lx & %08lx (%2d) = %02x = %5d  %8x\n",
  1201.         i, help->seq,help->mask,help->len,help->key,(signed char)help->key,
  1202.         help->seq & (~help->mask));
  1203.    }
  1204. #endif
  1205.  
  1206. }
  1207.  
  1208. #undef E
  1209.  
  1210. static struct myhqt myhuff0[256],myhuff1[256],myhuff2[256];
  1211. static int          myhufflen0=0,myhufflen1=0,myhufflen2=0;
  1212.  
  1213. static void readhqt(w,h,n)
  1214.   dim w,h;
  1215.   int n;
  1216.  {
  1217.   uBYTE *ptr;
  1218.  
  1219.   melde("readhqt\n");
  1220.   EREADBUF;
  1221.   ptr = sbuffer;
  1222.  
  1223.   readhqtsub((struct pcdhqt *)ptr,myhuff0,&myhufflen0);
  1224.  
  1225.   if(n<2) return;
  1226.   ptr+= 1 + 4* myhufflen0;
  1227.   readhqtsub((struct pcdhqt *)ptr,myhuff1,&myhufflen1);
  1228.  
  1229.   if(n<3) return;
  1230.   ptr+= 1 + 4* myhufflen1;
  1231.   readhqtsub((struct pcdhqt *)ptr,myhuff2,&myhufflen2);
  1232.  
  1233. }
  1234.  
  1235.  
  1236.  
  1237.  
  1238.  
  1239. static void decode(w,h,f,f1,f2,autosync)
  1240.   dim w,h;
  1241.   implane *f,*f1,*f2;
  1242.   int autosync;
  1243.  {int i,htlen,sum;
  1244.   unsigned long sreg,maxwidth;
  1245.   unsigned int inh,n,zeile,segment,ident;
  1246.   struct myhqt *htptr,*hp;
  1247.  
  1248.   uBYTE *nptr;
  1249.   uBYTE *lptr;
  1250.  
  1251.   melde("decode\n");
  1252. #define nextbuf  {  nptr=sbuffer;  EREADBUF; }
  1253. #define checkbuf { if (nptr >= sbuffer + sizeof(sbuffer)) nextbuf; }
  1254. #define shiftout(n){ sreg<<=n; inh-=n; \
  1255.                      while (inh<=24) \
  1256.                       {checkbuf; \
  1257.                        sreg |= ((unsigned long)(*(nptr++)))<<(24-inh);\
  1258.                        inh+=8;\
  1259.                       }\
  1260.                     }
  1261. #define issync ((sreg & 0xffffff00) == 0xfffffe00)
  1262. #define seeksync { while (!issync) shiftout(1);}
  1263.  
  1264.  
  1265.   if( f  && ((! f->im) || ( f->iheight < h  ) ||  (f->iwidth<w  ))) error(E_INTERN);
  1266.   if( f1 && ((!f1->im) || (f1->iheight < h/2) || (f1->iwidth<w/2))) error(E_INTERN);
  1267.   if( f2 && ((!f2->im) || (f2->iheight < h/2) || (f2->iwidth<w/2))) error(E_INTERN);
  1268.  
  1269.   htlen=sreg=maxwidth=0;
  1270.   htptr=0;
  1271.   nextbuf;
  1272.   inh=32;
  1273.   lptr=0;
  1274.   shiftout(16);
  1275.   shiftout(16);
  1276.  
  1277.   if(autosync) seeksync;
  1278.  
  1279.   n=0;
  1280.   for(;;)
  1281.    {
  1282.     if (issync)
  1283.      {shiftout(24);
  1284.       ident=sreg>>16;
  1285.       shiftout(16);
  1286.  
  1287.       zeile=(ident>>1) & 0x1fff;
  1288.       segment=ident>>14;
  1289.  
  1290. #ifdef DEBUG
  1291.       fprintf(stderr,"Ident %4x Zeile:  %6d  Segment %3d Pixels bisher: %5d   Position: %8lx\n",
  1292.           ident,zeile,segment,n,bufpos);
  1293. #endif
  1294.  
  1295.  
  1296.       if(lptr && (n!=maxwidth)) error(E_SEQ1);
  1297.       n=0;
  1298.  
  1299.       if(zeile==h) {RPRINT; return; }
  1300.       if(zeile >h) error(E_SEQ2);
  1301.  
  1302.       switch(segment)
  1303.        {
  1304.         case 0: if((!f) && autosync) {seeksync; break;}
  1305.                 if(!f) error(E_SEQ7);
  1306.                 lptr=f->im + zeile*f->mwidth;
  1307.                 maxwidth=f->iwidth;
  1308.                 htlen=myhufflen0;
  1309.                 htptr=myhuff0;
  1310.                 break;
  1311.  
  1312.         case 2: if((!f1) && autosync) {seeksync; break;}
  1313.                 if(!f1) error(E_SEQ7);
  1314.                 lptr=f1->im + (zeile>>1)*f1->mwidth;
  1315.                 maxwidth=f1->iwidth;
  1316.                 htlen=myhufflen1;
  1317.                 htptr=myhuff1;
  1318.                 break;
  1319.  
  1320.         case 3: if((!f2) && autosync) {seeksync; break;}
  1321.                 if(!f2) error(E_SEQ7);
  1322.                 lptr=f2->im + (zeile>>1)*f2->mwidth;
  1323.                 maxwidth=f2->iwidth;
  1324.                 htlen=myhufflen2;
  1325.                 htptr=myhuff2;
  1326.                 break;
  1327.  
  1328.         default:error(E_SEQ3);
  1329.         }
  1330.      }
  1331.     else
  1332.      {
  1333. /*      if((!lptr) || (n>maxwidth)) error(E_SEQ4);*/
  1334.       if(!lptr)      error(E_SEQ6);
  1335.       if(n>maxwidth) error(E_SEQ4);
  1336.       for(i=0,hp=htptr;(i<htlen) && ((sreg & hp->mask)!= hp->seq); i++,hp++);
  1337.       if(i>=htlen) error(E_SEQ5);
  1338.  
  1339.       sum=((int)(*lptr)) + ((sBYTE)hp->key);
  1340.       NORM(sum);
  1341.       *(lptr++) = sum;
  1342.  
  1343.       n++;
  1344.       shiftout(hp->len);
  1345.  
  1346.      }
  1347.  
  1348.    }
  1349.  
  1350.  
  1351. #undef nextbuf
  1352. #undef checkbuf
  1353. #undef shiftout
  1354. #undef issync
  1355. #undef seeksync
  1356.  
  1357.  }
  1358.  
  1359.  
  1360.  
  1361.  
  1362. static void clear(l,n)
  1363.   implane *l;
  1364.   int n;
  1365. { dim x,y;
  1366.   uBYTE *ptr;
  1367.  
  1368.   ptr=l->im;
  1369.   for (x=0;x<l->mwidth;x++)
  1370.     for (y=0; y<l->mheight;y++)
  1371.       *(ptr++)=n;
  1372. }
  1373.  
  1374.  
  1375.  
  1376. #define slen 3072
  1377.  
  1378. static void sharpit(l)
  1379.   implane *l;
  1380.  {int x,y,h,w,mw,akk;
  1381.   uBYTE f1[slen],f2[slen],*old,*akt,*ptr,*work,*help,*optr;
  1382.  
  1383.   if((!l) || (!l->im)) error(E_INTERN);
  1384.   if(l->iwidth > slen) error(E_INTERN);
  1385.  
  1386.   old=f1; akt=f2;
  1387.   h=l->iheight;
  1388.   w=l->iwidth;
  1389.   mw=l->mwidth;
  1390.  
  1391.   for(y=1;y<h-1;y++)
  1392.    {
  1393.     ptr=l->im+ y*mw;
  1394.     optr=ptr-mw;
  1395.     work=akt;
  1396.  
  1397.     *(work++)= *(ptr++);
  1398.     for(x=1;x<w-1;x++)
  1399.      {  akk = 5*((int)ptr[0])- ((int)ptr[1])  - ((int)ptr[-1])
  1400.                               - ((int)ptr[mw]) - ((int)ptr[-mw]);
  1401.         NORM(akk);
  1402.         *(work++)=akk;
  1403.         ptr++;
  1404.      }
  1405.  
  1406.     *(work++)= *(ptr++);
  1407.  
  1408.     if(y>1) memcpy(optr,old,w);
  1409.     help=old;old=akt;akt=help;
  1410.  
  1411.    }
  1412.  
  1413.  
  1414.  
  1415.   akt=optr+mw;
  1416.   for(x=0;x<w;x++)
  1417.     *(akt++) = *(old++);
  1418.  }
  1419.  
  1420.  
  1421. #undef slen
  1422.  
  1423.  
  1424.  
  1425.  
  1426.  
  1427.  
  1428. static int testbegin()
  1429.  {int i,j;
  1430.   for(i=j=0;i<32;i++)
  1431.     if(sbuffer[i]==0xff) j++;
  1432.  
  1433.   return (j>30);
  1434.  
  1435.  }
  1436.  
  1437. static long Skip4Base()
  1438.   {long cd_offset,cd_offhelp;
  1439.  
  1440.    cd_offset = L_Head + L_Base16 + L_Base4 + L_Base ;
  1441.    SEEK(cd_offset+3);
  1442.    EREADBUF;
  1443.    cd_offhelp=(((long)sbuffer[510])<<8)|sbuffer[511] + 1;
  1444.  
  1445.    cd_offset+=cd_offhelp;
  1446.  
  1447.    SEEK(cd_offset);
  1448.    EREADBUF;
  1449.    while(!testbegin())
  1450.     {cd_offset++;
  1451.      EREADBUF;
  1452.     }
  1453.    return cd_offset;
  1454.   }
  1455.