home *** CD-ROM | disk | FTP | other *** search
/ rtsi.com / 2014.01.www.rtsi.com.tar / www.rtsi.com / OS9 / OSK / NETWORK / netpbm_src.lzh / NETPBM / PPM / hpcdtoppm.c < prev    next >
C/C++ Source or Header  |  1996-11-18  |  35KB  |  1,428 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.  
  410.   if(!(fin=fopen(pcdname,"r"))) error(E_READ);
  411.  
  412.   if(do_info || (turn==T_AUTO)) 
  413.    { SEEK(1);
  414.      EREADBUF;
  415.    }
  416.  
  417.   if(turn==T_AUTO)
  418.    {
  419.     switch(sbuffer[0xe02 & 0x7ff]&0x03)
  420.      {case 0x00: turn=T_NONE;  break;
  421.       case 0x01: turn=T_LEFT;  break;
  422.       case 0x03: turn=T_RIGHT; break;
  423.       default: error(E_TCANT);
  424.      }
  425.    }
  426.  
  427.   if(do_info) druckeid();
  428.  
  429.  
  430.  
  431.  
  432.  
  433.   switch(size)
  434.    {
  435.     case S_Base16: w=BaseW/4;
  436.                    h=BaseH/4;
  437.                    planealloc(&Luma   ,w,h);
  438.                    planealloc(&Chroma1,w,h);
  439.                    planealloc(&Chroma2,w,h);
  440.  
  441.                    if(!do_overskip)
  442.                      { SEEK(L_Head+1);
  443.                        error(readplain(w,h,&Luma,&Chroma1,&Chroma2));
  444.                        interpolate(&Chroma1);
  445.                        interpolate(&Chroma2);
  446.                      }
  447.                    else
  448.                      { SEEK(L_Head+1);
  449.                        error(readplain(w,h,&Luma,nullplane,nullplane));
  450.                        SEEK(L_Head+L_Base16+1);
  451.                        error(readplain(2*w,2*h,nullplane,&Chroma1,&Chroma2));
  452.                      }
  453.                     
  454.  
  455.                    ycctorgb(w,h,&Luma,&Chroma1,&Chroma2);
  456.                    /* Now Luma holds red, Chroma1 hold green, Chroma2 holds blue */
  457.  
  458.                    if(!ppmname) fout=stdout;
  459.                    else
  460.                     {if (!(fout=fopen(ppmname,"w"))) error(E_WRITE);
  461.             }
  462.                    writepicture(w,h,&Luma,&Chroma1,&Chroma2,turn);
  463.  
  464.                    break;
  465.  
  466.     case S_Base4:  w=BaseW/2;
  467.                    h=BaseH/2;
  468.                    planealloc(&Luma   ,w,h);
  469.                    planealloc(&Chroma1,w,h);
  470.                    planealloc(&Chroma2,w,h);
  471.  
  472.  
  473.  
  474.                   if(!do_overskip)
  475.                      { SEEK(L_Head+L_Base16+1);
  476.                        error(readplain(w,h,&Luma,&Chroma1,&Chroma2));
  477.                        interpolate(&Chroma1);
  478.                        interpolate(&Chroma2);
  479.                      }
  480.                    else
  481.                      { SEEK(L_Head+L_Base16+1);
  482.                        error(readplain(w,h,&Luma,nullplane,nullplane));
  483.                        SEEK(L_Head+L_Base16+L_Base4+1); 
  484.                        error(readplain(2*w,2*h,nullplane,&Chroma1,&Chroma2));
  485.                      }
  486.                    ycctorgb(w,h,&Luma,&Chroma1,&Chroma2);
  487.                    /* Now Luma holds red, Chroma1 hold green, Chroma2 holds blue */
  488.  
  489.                    if(!ppmname) fout=stdout;
  490.                    else
  491.                     {if (!(fout=fopen(ppmname,"w"))) error(E_WRITE);
  492.             }
  493.                    writepicture(w,h,&Luma,&Chroma1,&Chroma2,turn);
  494.  
  495.                    break;
  496.  
  497.     case S_Base:   w=BaseW;
  498.                    h=BaseH;
  499.  
  500.                    if(!do_overskip)
  501.                      { planealloc(&Luma   ,w,h);
  502.                        planealloc(&Chroma1,w,h);
  503.                        planealloc(&Chroma2,w,h);
  504.                        SEEK(L_Head+L_Base16+L_Base4+1);
  505.                        error(readplain(w,h,&Luma,&Chroma1,&Chroma2));
  506.                        interpolate(&Chroma1);
  507.                        interpolate(&Chroma2);
  508.                      }
  509.                    else
  510.                      { planealloc(&Luma   ,  w,  h);
  511.                        planealloc(&Chroma1,2*w,2*h);
  512.                        planealloc(&Chroma2,2*w,2*h);
  513.                        SEEK(L_Head+L_Base16+L_Base4+1);
  514.                        error(readplain(w,h,&Luma,&Chroma1,&Chroma2));
  515.                        interpolate(&Chroma1);
  516.                        interpolate(&Chroma2);
  517.                        interpolate(&Chroma1);
  518.                        interpolate(&Chroma2);
  519.  
  520.                        cd_offset=Skip4Base();
  521.                        SEEK(cd_offset+10);          EREADBUF;    cd_offhelp=(((long)sbuffer[2])<<8)|sbuffer[3];
  522.                        SEEK(cd_offset+12);          readhqt(w,h,3);
  523.                        SEEK(cd_offset+cd_offhelp);  decode(4*w,4*h,nullplane,&Chroma1,&Chroma2,1);
  524.  
  525.                        halve(&Chroma1);
  526.                        halve(&Chroma2);
  527.                      }
  528.                    ycctorgb(w,h,&Luma,&Chroma1,&Chroma2);
  529.                    /* Now Luma holds red, Chroma1 hold green, Chroma2 holds blue */
  530.  
  531.                    if(!ppmname) fout=stdout;
  532.                    else
  533.                     {if (!(fout=fopen(ppmname,"w"))) error(E_WRITE);
  534.             }
  535.                    writepicture(w,h,&Luma,&Chroma1,&Chroma2,turn);
  536.  
  537.                    break;
  538.  
  539.     case S_4Base:  w=BaseW*2;
  540.                    h=BaseH*2;
  541.                    planealloc(&Luma,w,h);
  542.                    planealloc(&Chroma1,w,h);
  543.                    planealloc(&Chroma2,w,h);
  544.  
  545.                   if(!do_overskip)
  546.                      {SEEK(L_Head+L_Base16+L_Base4+1);
  547.                       error(readplain(w/2,h/2,&Luma,&Chroma1,&Chroma2));
  548.                       interpolate(&Luma);
  549.                       interpolate(&Chroma1);
  550.                       interpolate(&Chroma1);
  551.                       interpolate(&Chroma2);
  552.                       interpolate(&Chroma2);
  553.  
  554.                       if(do_diff) {clear(&Luma,128);clear(&Chroma1,156);clear(&Chroma2,137);}
  555.  
  556.                       cd_offset = L_Head + L_Base16 + L_Base4 + L_Base ;
  557.                       SEEK(cd_offset + 4);     readhqt(w,h,1);
  558.                       SEEK(cd_offset + 5);     decode(w,h,&Luma,nullplane,nullplane,0);
  559.                      }
  560.                    else
  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.                       cd_offset = L_Head + L_Base16 + L_Base4 + L_Base ;
  570.                       SEEK(cd_offset + 4);     readhqt(w,h,1);
  571.                       SEEK(cd_offset + 5);     decode(w,h,&Luma,nullplane,nullplane,0);
  572.  
  573.                       cd_offset=ftell(fin);if(cd_offset % SECSIZE) error(E_POS);cd_offset/=SECSIZE;
  574.                       SEEK(cd_offset+10);          EREADBUF;    cd_offhelp=(((long)sbuffer[2])<<8)|sbuffer[3];
  575.                       SEEK(cd_offset+12);          readhqt(w,h,3);
  576.                       SEEK(cd_offset+cd_offhelp);  decode(2*w,2*h,nullplane,&Chroma1,&Chroma2,1);
  577.                      
  578.                      }
  579.                    ycctorgb(w,h,&Luma,&Chroma1,&Chroma2);
  580.                    /* Now Luma holds red, Chroma1 hold green, Chroma2 holds blue */
  581.  
  582.                    if(!ppmname) fout=stdout;
  583.                    else
  584.                     {if (!(fout=fopen(ppmname,"w"))) error(E_WRITE);
  585.             }
  586.                    writepicture(w,h,&Luma,&Chroma1,&Chroma2,turn);
  587.  
  588.                    break;
  589.  
  590.     case S_16Base: w=BaseW*4;
  591.                    h=BaseH*4;
  592.                    planealloc(&Luma,w,h);
  593.                    planealloc(&Chroma1,w,h);
  594.                    planealloc(&Chroma2,w,h);
  595.  
  596.                    SEEK(L_Head+L_Base16+L_Base4+1);
  597.                    error(readplain(w/4,h/4,&Luma,&Chroma1,&Chroma2));
  598.                    interpolate(&Luma);
  599.                    interpolate(&Chroma1);
  600.                    interpolate(&Chroma1);
  601.                    interpolate(&Chroma2);
  602.                    interpolate(&Chroma2);
  603.  
  604.                    cd_offset = L_Head + L_Base16 + L_Base4 + L_Base ;
  605.                    SEEK(cd_offset + 4);       readhqt(w/2,h/2,1);
  606.                    SEEK(cd_offset + 5);       decode(w/2,h/2,&Luma,nullplane,nullplane,0);
  607.                    interpolate(&Luma);
  608.  
  609.                    if(do_diff) {clear(&Luma,128);clear(&Chroma1,156);clear(&Chroma2,137);}
  610.  
  611.                    cd_offset=ftell(fin);if(cd_offset % SECSIZE) error(E_POS);cd_offset/=SECSIZE;
  612.  
  613.                    SEEK(cd_offset+12);        readhqt(w,h,3);
  614.                    SEEK(cd_offset+14);        decode(w,h,&Luma,&Chroma1,&Chroma2,0);
  615.  
  616.                    interpolate(&Chroma1);
  617.                    interpolate(&Chroma2);
  618.  
  619.                    ycctorgb(w,h,&Luma,&Chroma1,&Chroma2);
  620.                    /* Now Luma holds red, Chroma1 hold green, Chroma2 holds blue */
  621.  
  622.                    if(!ppmname) fout=stdout;
  623.                    else
  624.                     {if (!(fout=fopen(ppmname,"w"))) error(E_WRITE);
  625.             }
  626.                    writepicture(w,h,&Luma,&Chroma1,&Chroma2,turn);
  627.  
  628.                    break;
  629.  
  630.     case S_Over:   w=BaseW/4;
  631.                    h=BaseH/4;
  632.              
  633.                    planealloc(&Luma   ,w,h);
  634.                    planealloc(&Chroma1,w,h);
  635.                    planealloc(&Chroma2,w,h);
  636.  
  637.                    for(bildnr=0;!feof(fin);bildnr++)
  638.             {
  639.                SEEK(5+SeBase16*bildnr);
  640.     
  641.                eret=readplain(w,h,&Luma,&Chroma1,&Chroma2);
  642.                        if(eret==E_READ) break;
  643.                        error(eret);
  644.  
  645.                interpolate(&Chroma1);
  646.                interpolate(&Chroma2);
  647.     
  648.                ycctorgb(w,h,&Luma,&Chroma1,&Chroma2);
  649.                /* Now Luma holds red, Chroma1 hold green, Chroma2 holds blue */
  650.     
  651.                        sprintf(nbuf,"%s%04d",ppmname,bildnr+1);
  652.                if (!(fout=fopen(nbuf,"w"))) error(E_WRITE);
  653.                writepicture(w,h,&Luma,&Chroma1,&Chroma2,turn);
  654.              }
  655.                    break;
  656.  
  657.      default: error(E_INTERN); 
  658.    }
  659.  
  660.  
  661.  
  662.  
  663. exit(0);
  664.  
  665.  
  666.  
  667. }
  668. #undef ASKIP
  669.  
  670.  
  671.  
  672.  
  673.  
  674.  
  675. static enum ERRORS readplain(w,h,l,c1,c2)
  676.   dim w,h;
  677.   implane *l,*c1,*c2;
  678.  {dim i;
  679.   uBYTE *pl=0,*pc1=0,*pc2=0;
  680.   melde("readplain\n");
  681.  
  682.   if(l)
  683.    { if ((l->mwidth<w) || (l->mheight<h) || (!l->im)) error(E_INTERN);
  684.      l->iwidth=w;
  685.      l->iheight=h;
  686.      pl=l->im;
  687.    }
  688.  
  689.   if(c1)
  690.    { if ((c1->mwidth<w/2) || (c1->mheight<h/2) || (!c1->im)) error(E_INTERN);
  691.      c1->iwidth=w/2;
  692.      c1->iheight=h/2;
  693.      pc1=c1->im;
  694.    }
  695.  
  696.   if(c2)
  697.    { if ((c2->mwidth<w/2) || (c2->mheight<h/2) || (!c2->im)) error(E_INTERN);
  698.      c2->iwidth=w/2;
  699.      c2->iheight=h/2;
  700.      pc2=c2->im;
  701.    }
  702.  
  703.   for(i=0;i<h/2;i++)
  704.    {
  705.     if(pl)
  706.      { 
  707.        if(fread(pl,w,1,fin)<1) return(E_READ);
  708.        pl+= l->mwidth;
  709.  
  710.        if(fread(pl,w,1,fin)<1) return(E_READ);
  711.        pl+= l->mwidth;
  712.      }
  713.     else SKIPr(2*w);
  714.      
  715.     if(pc1)
  716.      { if(fread(pc1,w/2,1,fin)<1) return(E_READ);
  717.        pc1+= c1->mwidth;
  718.      }
  719.     else SKIPr(w/2);
  720.      
  721.     if(pc2)
  722.      { if(fread(pc2,w/2,1,fin)<1) return(E_READ);
  723.        pc2+= c2->mwidth;
  724.      }
  725.     else SKIPr(w/2);
  726.  
  727.  
  728.    }
  729.   RPRINT;
  730.   return E_NONE;
  731.  }
  732.  
  733.  
  734.  
  735.  
  736.  
  737.  
  738.  
  739.  
  740.  
  741.  
  742.  
  743. static void interpolate(p)
  744.   implane *p;
  745.  {dim w,h,x,y,yi;
  746.   uBYTE *optr,*nptr,*uptr;
  747.  
  748.   melde("interpolate\n");
  749.   if ((!p) || (!p->im)) error(E_INTERN);
  750.  
  751.   w=p->iwidth;
  752.   h=p->iheight;
  753.  
  754.   if(p->mwidth  < 2*w ) error(E_INTERN);
  755.   if(p->mheight < 2*h ) error(E_INTERN);
  756.  
  757.  
  758.   p->iwidth=2*w;
  759.   p->iheight=2*h;
  760.  
  761.  
  762.   for(y=0;y<h;y++)
  763.    {yi=h-1-y;
  764.     optr=p->im+  yi*p->mwidth + (w-1);
  765.     nptr=p->im+2*yi*p->mwidth + (2*w - 2);
  766.  
  767.     nptr[0]=nptr[1]=optr[0];
  768.  
  769.     for(x=1;x<w;x++)
  770.      { optr--; nptr-=2;
  771.        nptr[0]=optr[0];
  772.        nptr[1]=(((int)optr[0])+((int)optr[1])+1)>>1;
  773.      }
  774.     }
  775.  
  776.   for(y=0;y<h-1;y++)
  777.    {optr=p->im + 2*y*p->mwidth;
  778.     nptr=optr+p->mwidth;
  779.     uptr=nptr+p->mwidth;
  780.  
  781.     for(x=0;x<w-1;x++)
  782.      {
  783.       nptr[0]=(((int)optr[0])+((int)uptr[0])+1)>>1;
  784.       nptr[1]=(((int)optr[0])+((int)optr[2])+((int)uptr[0])+((int)uptr[2])+2)>>2;
  785.       nptr+=2; optr+=2; uptr+=2;
  786.      }
  787.     *(nptr++)=(((int)*(optr++))+((int)*(uptr++))+1)>>1;
  788.     *(nptr++)=(((int)*(optr++))+((int)*(uptr++))+1)>>1;
  789.    }
  790.  
  791.  
  792.   optr=p->im + (2*h-2)*p->mwidth;
  793.   nptr=p->im + (2*h-1)*p->mwidth;
  794.   for(x=0;x<w;x++)
  795.    { *(nptr++) = *(optr++);  *(nptr++) = *(optr++); }
  796.  
  797.  }
  798.  
  799.  
  800.  
  801.  
  802.  
  803.  
  804.  
  805.  
  806.  
  807.  
  808. static void halve(p)
  809.   implane *p;
  810.  {dim w,h,x,y;
  811.   uBYTE *optr,*nptr;
  812.  
  813.   melde("halve\n");
  814.   if ((!p) || (!p->im)) error(E_INTERN);
  815.  
  816.   w=p->iwidth/=2;      
  817.   h=p->iheight/=2;     
  818.  
  819.  
  820.   for(y=0;y<h;y++)
  821.    {
  822.     nptr=(p->im) +   y*(p->mwidth);
  823.     optr=(p->im) + 2*y*(p->mwidth);
  824.  
  825.     for(x=0;x<w;x++,nptr++,optr+=2)
  826.      { *nptr = *optr;
  827.      }
  828.  
  829.    }
  830.  
  831.  }
  832.  
  833.  
  834.  
  835.  
  836.  
  837.  
  838.  
  839.  
  840.  
  841.  
  842.  
  843. #define BitShift 12
  844.  
  845. static void ycctorgb(w,h,l,c1,c2)
  846.   dim w,h;
  847.   implane *l,*c1,*c2;
  848.  {dim x,y;
  849.   uBYTE *pl,*pc1,*pc2;
  850.   long red,green,blue,i;
  851.   long L;
  852.   static int init=0;
  853.   static long XL[256],XC1[256],XC2[256],XC1g[256],XC2g[256];
  854.  
  855.   melde("ycctorgb\n");
  856.   if((!l ) || ( l->iwidth != w ) || ( l->iheight != h) || (! l->im)) error(E_INTERN);
  857.   if((!c1) || (c1->iwidth != w ) || (c1->iheight != h) || (!c1->im)) error(E_INTERN);
  858.   if((!c2) || (c2->iwidth != w ) || (c2->iheight != h) || (!c2->im)) error(E_INTERN);
  859.  
  860.   if(do_sharp) sharpit(l);
  861.   if(keep_ycc) return;
  862.  
  863.   if(!init)
  864.    {init=1;
  865.     for(i=0;i<256;i++)
  866.      {  XL[i]= 5564 * i + 2048;
  867.        XC1[i]= 9085 * i - 1417185;
  868.        XC2[i]= 7461 * i - 1022138;
  869.       XC1g[i]= 274934 - 1762 * i;
  870.       XC2g[i]= 520268 - 3798 * i; 
  871.      }
  872.    }
  873.  
  874.   for(y=0;y<h;y++)
  875.    {
  876.     pl =  l->im + y *  l->mwidth;
  877.     pc1= c1->im + y * c1->mwidth;
  878.     pc2= c2->im + y * c2->mwidth;
  879.  
  880.     for(x=0;x<w;x++)
  881.      {
  882.       L = XL[*pl]; 
  883.       red  =(L + XC2[*pc2]               )>>BitShift;
  884.       green=(L + XC1g[*pc1] + XC2g[*pc2] )>>BitShift; 
  885.       blue =(L + XC1[*pc1]               )>>BitShift;
  886.  
  887.       NORM(red);
  888.       NORM(green);
  889.       NORM(blue);
  890.  
  891.       *(pl++ )=red; 
  892.       *(pc1++)=green; 
  893.       *(pc2++)=blue;
  894.      }
  895.    }
  896.  }
  897. #undef BitShift
  898.  
  899.  
  900.  
  901.  
  902.  
  903.  
  904. static void writepicture(w,h,r,g,b,t)
  905.   dim w,h;
  906.   implane *r,*g,*b;
  907.   enum TURNS t;
  908.  {dim x,y;
  909.   register uBYTE *pr,*pg,*pb;
  910. #ifndef OWN_WRITE
  911.   pixel *pixrow;
  912.   register pixel* pP;
  913. #else
  914.   static uBYTE BUF[own_BUsize],*BUptr;
  915.   int   BUcount;
  916.  
  917. #define BUinit {BUcount=0;BUptr=BUF;}
  918. #define BUflush {fwrite(BUF,BUcount*3,1,fout);BUinit; }
  919. #define BUwrite(r,g,b) {if(BUcount>=own_BUsize/3) BUflush; *BUptr++ = r ; *BUptr++ = g ; *BUptr++ = b ; BUcount++;}
  920.  
  921. #endif
  922.  
  923.   melde("writepicture\n");
  924.   if((!r) || (r->iwidth != w ) || (r->iheight != h) || (!r->im)) error(E_INTERN);
  925.   if((!g) || (g->iwidth != w ) || (g->iheight != h) || (!g->im)) error(E_INTERN);
  926.   if((!b) || (b->iwidth != w ) || (b->iheight != h) || (!b->im)) error(E_INTERN);
  927.  
  928.   switch (t)
  929.    { case T_NONE:
  930. #ifndef OWN_WRITE
  931.               ppm_writeppminit(fout,w,h,(pixval) 255, 0);
  932.               pixrow = ppm_allocrow( w );
  933.           for(y=0;y<h;y++)
  934.            {
  935.         pr= r->im + y * r->mwidth;
  936.         pg= g->im + y * g->mwidth;
  937.         pb= b->im + y * b->mwidth;
  938.         
  939.              for(pP= pixrow,x=0;x<w;x++)
  940.          {
  941.           PPM_ASSIGN(*pP,((int)*pr),((int)*pg),((int)*pb));
  942.           pP++;  pr++;  pg++;  pb++;
  943.          }
  944.         ppm_writeppmrow( fout, pixrow, w, (pixval) 255, 0 );
  945.         
  946.            }
  947.           pm_close(fout);
  948. #else
  949.               fprintf(fout,PPM_Header,w,h);
  950.               BUinit;
  951.           for(y=0;y<h;y++)
  952.            {
  953.         pr= r->im + y * r->mwidth;
  954.         pg= g->im + y * g->mwidth;
  955.         pb= b->im + y * b->mwidth;
  956.         
  957.              for(x=0;x<w;x++) BUwrite(*pr++,*pg++,*pb++);        
  958.            }
  959.               BUflush;
  960.               if(ppmname) fclose(fout);
  961. #endif
  962.               break;
  963.      case T_RIGHT:
  964. #ifndef OWN_WRITE
  965.               ppm_writeppminit(fout,h,w,(pixval) 255, 0);
  966.               pixrow = ppm_allocrow( h );
  967.  
  968.           for(y=0;y<w;y++)
  969.            {
  970.         pr= r->im + r->mwidth * ( r->iheight - 1) + y;
  971.         pg= g->im + g->mwidth * ( g->iheight - 1) + y;
  972.         pb= b->im + b->mwidth * ( b->iheight - 1) + y;
  973.         
  974.         for(pP= pixrow,x=0;x<h;x++)
  975.          {
  976.           PPM_ASSIGN(*pP,((int)*pr),((int)*pg),((int)*pb));
  977.           pP++;      pr-= r->mwidth;  pg-= g->mwidth;  pb-= b->mwidth;
  978.          }
  979.         ppm_writeppmrow( fout, pixrow, h, (pixval) 255, 0 );
  980.         
  981.            }
  982.           pm_close(fout);
  983. #else
  984.               fprintf(fout,PPM_Header,h,w);
  985.               BUinit;
  986.           for(y=0;y<w;y++)
  987.            {
  988.         pr= r->im + r->mwidth * ( r->iheight - 1) + y;
  989.         pg= g->im + g->mwidth * ( g->iheight - 1) + y;
  990.         pb= b->im + b->mwidth * ( b->iheight - 1) + y;
  991.         
  992.              for(x=0;x<h;x++) 
  993.                 {BUwrite(*pr,*pg,*pb);    
  994.          pr-= r->mwidth;  pg-= g->mwidth;  pb-= b->mwidth;
  995.                 }    
  996.            }
  997.               BUflush;
  998.               if(ppmname) fclose(fout);
  999. #endif
  1000.               break;
  1001.  
  1002.       case T_LEFT:
  1003. #ifndef OWN_WRITE
  1004.               ppm_writeppminit(fout,h,w,(pixval) 255, 0);
  1005.               pixrow = ppm_allocrow( h );
  1006.  
  1007.           for(y=0;y<w;y++)
  1008.            {
  1009.         pr= r->im + r->iwidth - 1 - y;
  1010.         pg= g->im + g->iwidth - 1 - y;
  1011.         pb= b->im + b->iwidth - 1 - y;
  1012.         
  1013.         
  1014.         
  1015.         for(pP= pixrow,x=0;x<h;x++)
  1016.          {
  1017.           PPM_ASSIGN(*pP,((int)*pr),((int)*pg),((int)*pb));
  1018.           pP++;      pr+= r->mwidth;  pg+= g->mwidth;  pb+= b->mwidth;
  1019.          }
  1020.         ppm_writeppmrow( fout, pixrow, h, (pixval) 255, 0 );
  1021.         
  1022.            }
  1023.           pm_close(fout);
  1024. #else
  1025.               fprintf(fout,PPM_Header,h,w);
  1026.               BUinit;
  1027.           for(y=0;y<w;y++)
  1028.            {
  1029.         pr= r->im + r->iwidth - 1 - y;
  1030.         pg= g->im + g->iwidth - 1 - y;
  1031.         pb= b->im + b->iwidth - 1 - y;
  1032.         
  1033.              for(x=0;x<h;x++) 
  1034.                 {BUwrite(*pr,*pg,*pb);    
  1035.          pr+= r->mwidth;  pg+= g->mwidth;  pb+= b->mwidth;
  1036.                 }    
  1037.            }
  1038.               BUflush;
  1039.               if(ppmname) fclose(fout);
  1040.  
  1041. #endif
  1042.               break;
  1043.       default: error(E_INTERN);
  1044.     }
  1045.  }
  1046.  
  1047.  
  1048.  
  1049.  
  1050.  
  1051.  
  1052.  
  1053.  
  1054.  
  1055.  
  1056.  
  1057.  
  1058.  
  1059.  
  1060.  
  1061.  
  1062.  
  1063.  
  1064.  
  1065.  
  1066. struct ph1 
  1067.  {char  id1[8];
  1068.   uBYTE ww1[14];
  1069.   char  id2[20];
  1070.   char  id3[4*16+4];
  1071.   short ww2;
  1072.   char  id4[20];
  1073.   uBYTE ww3[2*16+1];
  1074.   char  id5[4*16];
  1075.   uBYTE idx[11*16];
  1076.  } ;
  1077.  
  1078.  
  1079. static void druckeid()
  1080. {int i;
  1081.  struct ph1 *d;
  1082.  char ss[100];
  1083.  
  1084.  d=(struct ph1 *)sbuffer;
  1085.  
  1086. #define dr(feld,kennung)   \
  1087.      strncpy(ss,feld,sizeof(feld));\
  1088.      ss[sizeof(feld)]=0;\
  1089.      fprintf(stderr,"%s: %s \n",kennung,ss);
  1090.  
  1091. #define db(feld) fprintf(stderr,"--%d\n",sizeof(feld)); for(i=0;i<sizeof(feld);i+=2) \
  1092.   fprintf(stderr,"%4d %6d\n",i,(signed int)((((unsigned int)feld[i])<<8)|feld[i+1]));\
  1093.   fprintf(stderr,"\n");
  1094.  
  1095. dr(d->id1,"Id1")
  1096. dr(d->id2,"Id2")
  1097. dr(d->id3,"Id3")
  1098. dr(d->id4,"Id4")
  1099. dr(d->id5,"Id5")
  1100.  
  1101. /*
  1102. db(d->ww1)
  1103. db(d->ww3)
  1104. db(d->idx)
  1105. */
  1106.  
  1107. #undef dr 
  1108. #undef db
  1109.  
  1110. }
  1111.  
  1112.  
  1113.  
  1114. struct pcdword
  1115.  { uBYTE high,low;
  1116.  };
  1117.  
  1118. static int lpt[1024];
  1119.  
  1120. static void readlpt(w,h)
  1121.   dim w,h;
  1122.  {int i;
  1123.   struct pcdword *ptr;
  1124.  
  1125.   EREADBUF;
  1126.  
  1127.   ptr = (struct pcdword *)sbuffer;
  1128.  
  1129.   for(i=0;i<h/4;i++,ptr++)
  1130.    {lpt[i] = ((int)ptr->high)<<8 | ptr->low ;
  1131.    }
  1132.  
  1133.  
  1134.   
  1135.  }
  1136.  
  1137.  
  1138.  
  1139. #define E ((unsigned long) 1)
  1140.  
  1141.  
  1142. static void readhqtsub(source,ziel,anzahl)
  1143.   struct pcdhqt *source;
  1144.   struct myhqt *ziel;
  1145.   int *anzahl;
  1146.  {int i;
  1147.   struct pcdquad *sub;
  1148.   struct myhqt *help;
  1149.   *anzahl=(source->entries)+1;
  1150.  
  1151.   for(i=0;i<*anzahl;i++)
  1152.    {sub = (struct pcdquad *)(((uBYTE *)source)+1+i*sizeof(*sub));
  1153.     help=ziel+i;
  1154.  
  1155.     help->seq = (((unsigned long) sub->highseq) << 24) |(((unsigned long) sub->lowseq) << 16);
  1156.     help->len = ((unsigned long) sub->len) +1;
  1157.     help->key = sub->key;
  1158.  
  1159. #ifdef DEBUGhuff
  1160.    fprintf(stderr," Anz: %d A1: %08x  A2: %08x X:%02x %02x %02x %02x Seq:  %08x   Laenge:  %d %d\n",
  1161.           *anzahl,sbuffer,sub,((uBYTE *)sub)[0],((uBYTE *)sub)[1],((uBYTE *)sub)[2],((uBYTE *)sub)[3],
  1162.           help->seq,help->len,sizeof(uBYTE));
  1163. #endif
  1164.  
  1165.     if(help->len > 16) error(E_HUFF);
  1166.  
  1167.     help->mask = ~ ( (E << (32-help->len)) -1); 
  1168.  
  1169.   }
  1170. #ifdef DEBUG
  1171.   for(i=0;i<*anzahl;i++)
  1172.    {help=ziel+i;
  1173.     fprintf(stderr,"H: %3d  %08lx & %08lx (%2d) = %02x = %5d  %8x\n",
  1174.         i, help->seq,help->mask,help->len,help->key,(signed char)help->key,
  1175.         help->seq & (~help->mask));
  1176.    }
  1177. #endif
  1178.  
  1179. }
  1180.  
  1181. #undef E
  1182.  
  1183. static struct myhqt myhuff0[256],myhuff1[256],myhuff2[256];
  1184. static int          myhufflen0=0,myhufflen1=0,myhufflen2=0;
  1185.  
  1186. static void readhqt(w,h,n)
  1187.   dim w,h;
  1188.   int n;
  1189.  {
  1190.   uBYTE *ptr;
  1191.  
  1192.   melde("readhqt\n");
  1193.   EREADBUF;
  1194.   ptr = sbuffer;
  1195.  
  1196.   readhqtsub((struct pcdhqt *)ptr,myhuff0,&myhufflen0);
  1197.  
  1198.   if(n<2) return;
  1199.   ptr+= 1 + 4* myhufflen0;
  1200.   readhqtsub((struct pcdhqt *)ptr,myhuff1,&myhufflen1);
  1201.  
  1202.   if(n<3) return;
  1203.   ptr+= 1 + 4* myhufflen1;
  1204.   readhqtsub((struct pcdhqt *)ptr,myhuff2,&myhufflen2);
  1205.  
  1206. }
  1207.  
  1208.  
  1209.  
  1210.  
  1211.  
  1212. static void decode(w,h,f,f1,f2,autosync)
  1213.   dim w,h;
  1214.   implane *f,*f1,*f2;
  1215.   int autosync;
  1216.  {int i,htlen,sum;
  1217.   unsigned long sreg,maxwidth;
  1218.   unsigned int inh,n,zeile,segment,ident;
  1219.   struct myhqt *htptr,*hp;
  1220.  
  1221.   uBYTE *nptr;
  1222.   uBYTE *lptr;
  1223.  
  1224.   melde("decode\n");
  1225. #define nextbuf  {  nptr=sbuffer;  EREADBUF; }
  1226. #define checkbuf { if (nptr >= sbuffer + sizeof(sbuffer)) nextbuf; }
  1227. #define shiftout(n){ sreg<<=n; inh-=n; \
  1228.                      while (inh<=24) \
  1229.                       {checkbuf; \
  1230.                        sreg |= ((unsigned long)(*(nptr++)))<<(24-inh);\
  1231.                        inh+=8;\
  1232.                       }\
  1233.                     }  
  1234. #define issync ((sreg & 0xffffff00) == 0xfffffe00) 
  1235. #define seeksync { while (!issync) shiftout(1);}
  1236.  
  1237.  
  1238.   if( f  && ((! f->im) || ( f->iheight < h  ) ||  (f->iwidth<w  ))) error(E_INTERN);
  1239.   if( f1 && ((!f1->im) || (f1->iheight < h/2) || (f1->iwidth<w/2))) error(E_INTERN);
  1240.   if( f2 && ((!f2->im) || (f2->iheight < h/2) || (f2->iwidth<w/2))) error(E_INTERN);
  1241.  
  1242.   htlen=sreg=maxwidth=0;
  1243.   htptr=0;
  1244.   nextbuf;
  1245.   inh=32;
  1246.   lptr=0;
  1247.   shiftout(16);
  1248.   shiftout(16);
  1249.  
  1250.   if(autosync) seeksync;
  1251.  
  1252.   n=0;
  1253.   for(;;)
  1254.    {
  1255.     if (issync)
  1256.      {shiftout(24);
  1257.       ident=sreg>>16;
  1258.       shiftout(16);
  1259.  
  1260.       zeile=(ident>>1) & 0x1fff;
  1261.       segment=ident>>14;
  1262.  
  1263. #ifdef DEBUG
  1264.       fprintf(stderr,"Ident %4x Zeile:  %6d  Segment %3d Pixels bisher: %5d   Position: %8lx\n",
  1265.           ident,zeile,segment,n,bufpos);
  1266. #endif
  1267.  
  1268.  
  1269.       if(lptr && (n!=maxwidth)) error(E_SEQ1);
  1270.       n=0;
  1271.  
  1272.       if(zeile==h) {RPRINT; return; }
  1273.       if(zeile >h) error(E_SEQ2);
  1274.  
  1275.       switch(segment)
  1276.        {
  1277.         case 0: if((!f) && autosync) {seeksync; break;}
  1278.                 if(!f) error(E_SEQ7);
  1279.                 lptr=f->im + zeile*f->mwidth;
  1280.                 maxwidth=f->iwidth;
  1281.                 htlen=myhufflen0;
  1282.                 htptr=myhuff0;
  1283.                 break;
  1284.  
  1285.         case 2: if((!f1) && autosync) {seeksync; break;}
  1286.                 if(!f1) error(E_SEQ7);
  1287.                 lptr=f1->im + (zeile>>1)*f1->mwidth;
  1288.                 maxwidth=f1->iwidth;
  1289.                 htlen=myhufflen1;
  1290.                 htptr=myhuff1;
  1291.                 break;
  1292.  
  1293.         case 3: if((!f2) && autosync) {seeksync; break;}
  1294.                 if(!f2) error(E_SEQ7);
  1295.                 lptr=f2->im + (zeile>>1)*f2->mwidth;
  1296.                 maxwidth=f2->iwidth;
  1297.                 htlen=myhufflen2;
  1298.                 htptr=myhuff2;
  1299.                 break;
  1300.  
  1301.         default:error(E_SEQ3);
  1302.     }
  1303.      }
  1304.     else
  1305.      {
  1306. /*      if((!lptr) || (n>maxwidth)) error(E_SEQ4);*/
  1307.       if(!lptr)      error(E_SEQ6);
  1308.       if(n>maxwidth) error(E_SEQ4);
  1309.       for(i=0,hp=htptr;(i<htlen) && ((sreg & hp->mask)!= hp->seq); i++,hp++);
  1310.       if(i>=htlen) error(E_SEQ5);
  1311.  
  1312.       sum=((int)(*lptr)) + ((sBYTE)hp->key);
  1313.       NORM(sum);
  1314.       *(lptr++) = sum;
  1315.  
  1316.       n++; 
  1317.       shiftout(hp->len);
  1318.  
  1319.      }
  1320.  
  1321.    }
  1322.  
  1323.  
  1324. #undef nextbuf  
  1325. #undef checkbuf 
  1326. #undef shiftout
  1327. #undef issync
  1328. #undef seeksync
  1329.  
  1330.  }
  1331.  
  1332.  
  1333.  
  1334.  
  1335. static void clear(l,n)
  1336.   implane *l;
  1337.   int n;
  1338. { dim x,y;
  1339.   uBYTE *ptr;
  1340.  
  1341.   ptr=l->im;
  1342.   for (x=0;x<l->mwidth;x++)
  1343.     for (y=0; y<l->mheight;y++)
  1344.       *(ptr++)=n;
  1345. }
  1346.  
  1347.  
  1348.  
  1349. #define slen 3072
  1350.  
  1351. static void sharpit(l)
  1352.   implane *l;
  1353.  {int x,y,h,w,mw,akk;
  1354.   uBYTE f1[slen],f2[slen],*old,*akt,*ptr,*work,*help,*optr;
  1355.  
  1356.   if((!l) || (!l->im)) error(E_INTERN);
  1357.   if(l->iwidth > slen) error(E_INTERN);
  1358.  
  1359.   old=f1; akt=f2;
  1360.   h=l->iheight;
  1361.   w=l->iwidth;
  1362.   mw=l->mwidth;
  1363.  
  1364.   for(y=1;y<h-1;y++)
  1365.    {
  1366.     ptr=l->im+ y*mw;
  1367.     optr=ptr-mw;
  1368.     work=akt;
  1369.  
  1370.     *(work++)= *(ptr++);
  1371.     for(x=1;x<w-1;x++)
  1372.      {  akk = 5*((int)ptr[0])- ((int)ptr[1])  - ((int)ptr[-1]) 
  1373.                               - ((int)ptr[mw]) - ((int)ptr[-mw]);
  1374.         NORM(akk);
  1375.         *(work++)=akk;
  1376.         ptr++;
  1377.      }
  1378.  
  1379.     *(work++)= *(ptr++);
  1380.  
  1381.     if(y>1) memcpy(optr,old,w);
  1382.     help=old;old=akt;akt=help;
  1383.      
  1384.    }
  1385.  
  1386.  
  1387.  
  1388.   akt=optr+mw;
  1389.   for(x=0;x<w;x++)
  1390.     *(akt++) = *(old++);
  1391.  }
  1392.  
  1393.  
  1394. #undef slen
  1395.  
  1396.  
  1397.  
  1398.  
  1399.  
  1400.  
  1401. static int testbegin()
  1402.  {int i,j;
  1403.   for(i=j=0;i<32;i++)
  1404.     if(sbuffer[i]==0xff) j++;
  1405.  
  1406.   return (j>30);
  1407.   
  1408.  }
  1409.  
  1410. static long Skip4Base()
  1411.   {long cd_offset,cd_offhelp;
  1412.    
  1413.    cd_offset = L_Head + L_Base16 + L_Base4 + L_Base ;
  1414.    SEEK(cd_offset+3);          
  1415.    EREADBUF;    
  1416.    cd_offhelp=(((long)sbuffer[510])<<8)|sbuffer[511] + 1;
  1417.  
  1418.    cd_offset+=cd_offhelp;
  1419.  
  1420.    SEEK(cd_offset);
  1421.    EREADBUF;
  1422.    while(!testbegin())
  1423.     {cd_offset++;
  1424.      EREADBUF;
  1425.     }
  1426.    return cd_offset;
  1427.   }
  1428.