home *** CD-ROM | disk | FTP | other *** search
/ PSION CD 2 / PsionCDVol2.iso / Programs / 720 / PDF090B4-SorceCode / pdf / Stream.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2000-09-30  |  80.5 KB  |  3,530 lines

  1. //========================================================================
  2. //
  3. // Stream.cc
  4. //
  5. // Copyright 1996 Derek B. Noonburg
  6. //
  7. //========================================================================
  8. //
  9. // Ported to EPOC by Sander van der Wal
  10. //
  11. // $Log: Stream.cpp $
  12. // Revision 1.4  2000-09-24 21:09:16+02  svdwal
  13. // memory leak fixed
  14. //
  15. // Revision 1.3  2000-09-20 20:34:26+02  svdwal
  16. // added bugfixes from xpdf 0.91
  17. //
  18. // Revision 1.2  2000-09-17 13:38:20+02  svdwal
  19. // Ported
  20. //
  21.  
  22. #ifdef __GNUC__
  23. #pragma implementation
  24. #endif
  25.  
  26. #ifndef __E32DEF_H__
  27. #include <e32def.h>
  28. #endif
  29.  
  30. // --o C library
  31. #include <stdlib.h>
  32. #include <ctype.h>
  33.  
  34. // --o GooLib
  35. #include "gmem.h"
  36.  
  37. // --o PdfLib
  38. #include "config.h"
  39. #include "Error.h"
  40. #include "Object.h"
  41. #include "Stream.h"
  42. #include "Stream-CCITT.h"
  43.  
  44. // --o Pdf
  45. #include "file_unlzw.h"
  46. #include "Pdf.rsg"
  47.  
  48.  
  49. //------------------------------------------------------------------------
  50.  
  51. #define headerSearchSize 1024    // read this many bytes at beginning of
  52.                 //   file to look for '%PDF'
  53.  
  54. //------------------------------------------------------------------------
  55. // Stream (base class)
  56. //------------------------------------------------------------------------
  57.  
  58. Stream::Stream() {
  59.   ref = 1;
  60. }
  61.  
  62. Stream::~Stream() {
  63. }
  64.  
  65. int Stream::getRawChar() {
  66.   error(-1, R_INTERNAL__CALLED_GETRAWCHAR___ON_NON_PREDICTOR_STREAM);
  67.   return EOF;
  68. }
  69.  
  70. char *Stream::getLine(char *buf, int size) {
  71.   register int i;
  72.   register int c;
  73.  
  74.   if (lookChar() == EOF)
  75.     return NULL;
  76.   for (i = 0; i < size - 1; ++i) {
  77.     c = getChar();
  78.     if (c == EOF || c == '\n')
  79.       break;
  80.     if (c == '\r') {
  81.       if ((c = lookChar()) == '\n')
  82.     getChar();
  83.       break;
  84.     }
  85.     buf[i] = c;
  86.   }
  87.   buf[i] = '\0';
  88.   return buf;
  89. }
  90.  
  91. void Stream::setPos(int /* pos */) {
  92.   error(-1, R_INTERNAL__CALLED_SETPOS___ON_NON_FILESTREAM);
  93. }
  94.  
  95. GString *Stream::getPSFilterL(char * /* indent */) {
  96.   return GString::NewL();
  97. }
  98.  
  99. Stream *Stream::addFiltersL(Object *dict) {
  100.   RAutoObject obj;
  101.   RAutoObject params;
  102.   Stream *str;
  103.  
  104.   str = this;
  105.   dict->dictLookupL("Filter", &obj);
  106.   if (obj.isNull()) {
  107.     obj.free();
  108.     dict->dictLookupL("F", &obj);
  109.   }
  110.   dict->dictLookupL("DecodeParms", ¶ms);
  111.   if (params.isNull()) {
  112.     params.free();
  113.     dict->dictLookupL("DP", ¶ms);
  114.   }
  115.   if (obj.isName()) {
  116.     str = makeFilterL(obj.getName(), str, ¶ms);
  117.   }
  118.   else if (obj.isArray()) {
  119.     RAutoObject obj2;
  120.     RAutoObject params2;
  121.     for (register TInt i = 0; i < obj.arrayGetLength(); ++i) {
  122.       obj.arrayGetL(i, &obj2);
  123.       if (params.isArray())
  124.         params.arrayGetL(i, ¶ms2);
  125.       else
  126.         params2.initNull();
  127.       if (obj2.isName()) {
  128.         str = makeFilterL(obj2.getName(), str, ¶ms2);
  129.       } else {
  130.         error(getPos(), R_BAD_FILTER_NAME);
  131.         str = new(ELeave) EOFStream(str);
  132.       }
  133.       obj2.free();
  134.       params2.free();
  135.     }
  136.   } 
  137.   else if (!obj.isNull()) {
  138.     error(getPos(), R_BAD__FILTER__ATTRIBUTE_IN_STREAM);
  139.   }
  140.   obj.free();
  141.   params.free();
  142.  
  143.   return str;
  144. }
  145.  
  146. Stream *Stream::makeFilterL(char *name, Stream *str, Object *params) {
  147.   int pred;            // parameters
  148.   int colors;
  149.   int bits;
  150.   int early;
  151.   int columns;
  152.   //Object obj;
  153.  
  154.   if (!strcmp(name, "ASCIIHexDecode") || !strcmp(name, "AHx")) {
  155.     str = new(ELeave) ASCIIHexStream(str);
  156.   } else if (!strcmp(name, "ASCII85Decode") || !strcmp(name, "A85")) {
  157.     str = new(ELeave) ASCII85Stream(str);
  158.   } else if (!strcmp(name, "LZWDecode") || !strcmp(name, "LZW")) {
  159.     RAutoObject obj;
  160.     pred = 1;
  161.     columns = 1;
  162.     colors = 1;
  163.     bits = 8;
  164.     early = 1;
  165.     if (params->isDict()) {
  166.       params->dictLookupL("Predictor", &obj);
  167.       if (obj.isInt())
  168.         pred = obj.getInt();
  169.       obj.free();
  170.       params->dictLookupL("Columns", &obj);
  171.       if (obj.isInt())
  172.         columns = obj.getInt();
  173.       obj.free();
  174.       params->dictLookupL("Colors", &obj);
  175.       if (obj.isInt())
  176.         colors = obj.getInt();
  177.       obj.free();
  178.       params->dictLookupL("BitsPerComponent", &obj);
  179.       if (obj.isInt())
  180.         bits = obj.getInt();
  181.       obj.free();
  182.       params->dictLookupL("EarlyChange", &obj);
  183.       if (obj.isInt())
  184.         early = obj.getInt();
  185.       obj.free();
  186.     }
  187.     LZWStream* lzwStr = new(ELeave) LZWStream(str, early);
  188.     lzwStr->ConstructL(pred, columns, colors, bits);
  189.     str = lzwStr;
  190.   } else if (!strcmp(name, "RunLengthDecode") || !strcmp(name, "RL")) {
  191.     str = new(ELeave) RunLengthStream(str);
  192.   } else if (!strcmp(name, "CCITTFaxDecode") || !strcmp(name, "CCF")) {
  193.     RAutoObject obj;
  194.     int encoding = 0;
  195.     GBool endOfLine = gFalse;
  196.     GBool byteAlign = gFalse;
  197.     columns = 1728;
  198.     int rows = 0;
  199.     GBool endOfBlock = gTrue;
  200.     GBool black = gFalse;
  201.     if (params->isDict()) {
  202.       params->dictLookupL("K", &obj);
  203.       if (obj.isInt()) {
  204.         encoding = obj.getInt();
  205.       }
  206.       obj.free();
  207.       params->dictLookupL("EndOfLine", &obj);
  208.       if (obj.isBool()) {
  209.         endOfLine = obj.getBool();
  210.       }
  211.       obj.free();
  212.       params->dictLookupL("EncodedByteAlign", &obj);
  213.       if (obj.isBool()) {
  214.         byteAlign = obj.getBool();
  215.       }
  216.       obj.free();
  217.       params->dictLookupL("Columns", &obj);
  218.       if (obj.isInt()) {
  219.         columns = obj.getInt();
  220.       }
  221.       obj.free();
  222.       params->dictLookupL("Rows", &obj);
  223.       if (obj.isInt()) {
  224.         rows = obj.getInt();
  225.       }
  226.       obj.free();
  227.       params->dictLookupL("EndOfBlock", &obj);
  228.       if (obj.isBool()) {
  229.         endOfBlock = obj.getBool();
  230.       }
  231.       obj.free();
  232.       params->dictLookupL("BlackIs1", &obj);
  233.       if (obj.isBool()) {
  234.         black = obj.getBool();
  235.       }
  236.       obj.free();
  237.     }
  238.     CCITTFaxStream* faxStr = new(ELeave) CCITTFaxStream(str, encoding, endOfLine, byteAlign,
  239.                  columns, rows, endOfBlock, black);
  240.     faxStr->ConstructL();
  241.     str = faxStr;
  242.   } else if (!strcmp(name, "DCTDecode") || !strcmp(name, "DCT")) {
  243.     str = new(ELeave) DCTStream(str);
  244.   } else if (!strcmp(name, "FlateDecode") || !strcmp(name, "Fl")) {
  245.     RAutoObject obj;
  246.     pred = 1;
  247.     columns = 1;
  248.     colors = 1;
  249.     bits = 8;
  250.     if (params->isDict()) {
  251.       params->dictLookupL("Predictor", &obj);
  252.       if (obj.isInt())
  253.         pred = obj.getInt();
  254.       obj.free();
  255.       params->dictLookupL("Columns", &obj);
  256.       if (obj.isInt())
  257.         columns = obj.getInt();
  258.       obj.free();
  259.       params->dictLookupL("Colors", &obj);
  260.       if (obj.isInt())
  261.         colors = obj.getInt();
  262.       obj.free();
  263.       params->dictLookupL("BitsPerComponent", &obj);
  264.       if (obj.isInt())
  265.         bits = obj.getInt();
  266.       obj.free();
  267.     }
  268.     FlateStream* flateStr = new(ELeave) FlateStream(str);
  269.     flateStr->ConstructL(pred, columns, colors, bits);
  270.     str = flateStr;
  271.   } else {
  272.     error(getPos(), R_UNKNOWN_FILTER___S_, name);
  273.     str = new(ELeave) EOFStream(str);
  274.   }
  275.   return str;
  276. }
  277.  
  278. void Stream::enableEncryption(RC4KEY* /*rc4Key*/)
  279. {
  280.   error(-1, R_NO_FILESTREAM__NO_DECRYPTION);
  281. }
  282.  
  283. //------------------------------------------------------------------------
  284. // ImageStream
  285. //------------------------------------------------------------------------
  286.  
  287. ImageStream::ImageStream(Stream *str, int width, int nComps, int nBits) {
  288.   this->str = str;
  289.   this->width = width;
  290.   this->nComps = nComps;
  291.   this->nBits = nBits;
  292. }
  293.  
  294. void ImageStream::ConstructL()
  295. {
  296.   int imgLineSize;
  297.   nVals = width * nComps;
  298.   if (nBits == 1) {
  299.     imgLineSize = (nVals + 7) & ~7;
  300.   } else {
  301.     imgLineSize = nVals;
  302.   }
  303.   imgLine = (Guchar *)User::AllocL(imgLineSize * sizeof(Guchar));
  304.   imgIdx = nVals;
  305. }
  306.  
  307. ImageStream::~ImageStream() {
  308.   User::Free(imgLine);
  309. }
  310.  
  311. void ImageStream::reset() {
  312.   str->reset();
  313. }
  314.  
  315. GBool ImageStream::getPixel(Guchar *pix) {
  316.   register int i;
  317.  
  318.   if (imgIdx >= nVals) {
  319.  
  320.     // read one line of image pixels
  321.     if (nBits == 1) {
  322.       register int c;
  323.       for (i = 0; i < nVals; i += 8) {
  324.         c = str->getChar();
  325.         imgLine[i+0] = (Guchar)((c >> 7) & 1);
  326.         imgLine[i+1] = (Guchar)((c >> 6) & 1);
  327.         imgLine[i+2] = (Guchar)((c >> 5) & 1);
  328.         imgLine[i+3] = (Guchar)((c >> 4) & 1);
  329.         imgLine[i+4] = (Guchar)((c >> 3) & 1);
  330.         imgLine[i+5] = (Guchar)((c >> 2) & 1);
  331.         imgLine[i+6] = (Guchar)((c >> 1) & 1);
  332.         imgLine[i+7] = (Guchar)(c & 1);
  333.       }
  334.     } 
  335.     else if (nBits == 8) {
  336.       for (i = 0; i < nVals; ++i) {
  337.         imgLine[i] = str->getChar();
  338.       }
  339.     } 
  340.     else {
  341.       Gulong bitMask = (1 << nBits) - 1;
  342.       register Gulong buf = 0;
  343.       register int bits = 0;
  344.       for (i = 0; i < nVals; ++i) {
  345.         if (bits < nBits) {
  346.           buf = (buf << 8) | (str->getChar() & 0xff);
  347.           bits += 8;
  348.         }
  349.         imgLine[i] = (Guchar)((buf >> (bits - nBits)) & bitMask);
  350.         bits -= nBits;
  351.       }
  352.     }
  353.  
  354.     // reset to start of line
  355.     imgIdx = 0;
  356.   }
  357.  
  358.   for (i = 0; i < nComps; ++i)
  359.     pix[i] = imgLine[imgIdx++];
  360.   return gTrue;
  361. }
  362.  
  363. void ImageStream::skipLine() {
  364.   int n, i;
  365.  
  366.   n = (nVals * nBits + 7) >> 3;
  367.   for (i = 0; i < n; ++i) {
  368.     str->getChar();
  369.   }
  370. }
  371.  
  372. //------------------------------------------------------------------------
  373. // StreamPredictor
  374. //------------------------------------------------------------------------
  375.  
  376. StreamPredictor::StreamPredictor(Stream *str, int predictor,
  377.                  int width, int nComps, int nBits) {
  378.   this->str = str;
  379.   this->predictor = predictor;
  380.   this->width = width;
  381.   this->nComps = nComps;
  382.   this->nBits = nBits;
  383. }
  384.  
  385. void StreamPredictor::ConstructL()
  386. {
  387.   nVals = width * nComps;
  388.   pixBytes = (nComps * nBits + 7) >> 3;
  389.   rowBytes = ((nVals * nBits + 7) >> 3) + pixBytes;
  390.   predLine = (Guchar *)User::AllocL(rowBytes);
  391.   memset(predLine, 0, rowBytes);
  392.   predIdx = rowBytes;
  393. }
  394.  
  395. StreamPredictor::~StreamPredictor() {
  396.   User::Free(predLine);
  397. }
  398.  
  399. int StreamPredictor::lookChar() {
  400.   if (predIdx >= rowBytes) {
  401.     if (!getNextLine()) {
  402.       return EOF;
  403.     }
  404.   }
  405.   return predLine[predIdx];
  406. }
  407.  
  408. int StreamPredictor::getChar() {
  409.   if (predIdx >= rowBytes) {
  410.     if (!getNextLine()) {
  411.       return EOF;
  412.     }
  413.   }
  414.   return predLine[predIdx++];
  415. }
  416.  
  417. GBool StreamPredictor::getNextLine() {
  418.   int curPred;
  419.   Guchar upLeftBuf[4];
  420.   int left, up, upLeft, p, pa, pb, pc;
  421.   int c;
  422.   Gulong inBuf, outBuf, bitMask;
  423.   int inBits, outBits;
  424.   int i, j, k;
  425.  
  426.   // get PNG optimum predictor number
  427.   if (predictor == 15) {
  428.     if ((curPred = str->getRawChar()) == EOF) {
  429.       return gFalse;
  430.     }
  431.     curPred += 10;
  432.   } else {
  433.     curPred = predictor;
  434.   }
  435.  
  436.   // read the raw line, apply PNG (byte) predictor
  437.   upLeftBuf[0] = upLeftBuf[1] = upLeftBuf[2] = upLeftBuf[3] = 0;
  438.   for (i = pixBytes; i < rowBytes; ++i) {
  439.     upLeftBuf[3] = upLeftBuf[2];
  440.     upLeftBuf[2] = upLeftBuf[1];
  441.     upLeftBuf[1] = upLeftBuf[0];
  442.     upLeftBuf[0] = predLine[i];
  443.     if ((c = str->getRawChar()) == EOF) {
  444.       break;
  445.     }
  446.     switch (curPred) {
  447.     case 11:            // PNG sub
  448.       predLine[i] = predLine[i - pixBytes] + (Guchar)c;
  449.       break;
  450.     case 12:            // PNG up
  451.       predLine[i] = predLine[i] + (Guchar)c;
  452.       break;
  453.     case 13:            // PNG average
  454.       predLine[i] = ((predLine[i - pixBytes] + predLine[i]) >> 1) +
  455.                 (Guchar)c;
  456.       break;
  457.     case 14:            // PNG Paeth
  458.       left = predLine[i - pixBytes];
  459.       up = predLine[i];
  460.       upLeft = upLeftBuf[pixBytes];
  461.       p = left + up - upLeft;
  462.       if ((pa = p - left) < 0)
  463.     pa = -pa;
  464.       if ((pb = p - up) < 0)
  465.     pb = -pb;
  466.       if ((pc = p - upLeft) < 0)
  467.     pc = -pc;
  468.       if (pa <= pb && pa <= pc)
  469.     predLine[i] = pa + (Guchar)c;
  470.       else if (pb <= pc)
  471.     predLine[i] = pb + (Guchar)c;
  472.       else
  473.     predLine[i] = pc + (Guchar)c;
  474.       break;
  475.     case 10:            // PNG none
  476.     default:            // no predictor or TIFF predictor
  477.       predLine[i] = (Guchar)c;
  478.       break;
  479.     }
  480.   }
  481.  
  482.   // apply TIFF (component) predictor
  483.   //~ this is completely untested
  484.   if (predictor == 2) {
  485.     if (nBits == 1) {
  486.       inBuf = predLine[pixBytes - 1];
  487.       for (i = pixBytes; i < rowBytes; i += 8) {
  488.     // 1-bit add is just xor
  489.     inBuf = (inBuf << 8) | predLine[i];
  490.     predLine[i] ^= inBuf >> nComps;
  491.       }
  492.     } else if (nBits == 8) {
  493.       for (i = pixBytes; i < rowBytes; ++i) {
  494.     predLine[i] += predLine[i - nComps];
  495.       }
  496.     } else {
  497.       upLeftBuf[0] = upLeftBuf[1] = upLeftBuf[2] = upLeftBuf[3] = 0;
  498.       bitMask = (1 << nBits) - 1;
  499.       inBuf = outBuf = 0;
  500.       inBits = outBits = 0;
  501.       j = k = pixBytes;
  502.       for (i = 0; i < nVals; ++i) {
  503.     if (inBits < nBits) {
  504.       inBuf = (inBuf << 8) | (predLine[j++] & 0xff);
  505.       inBits += 8;
  506.     }
  507.     upLeftBuf[3] = upLeftBuf[2];
  508.     upLeftBuf[2] = upLeftBuf[1];
  509.     upLeftBuf[1] = upLeftBuf[0];
  510.     upLeftBuf[0] = (upLeftBuf[nComps] +
  511.             (inBuf >> (inBits - nBits))) & bitMask;
  512.     outBuf = (outBuf << nBits) | upLeftBuf[0];
  513.     inBits -= nBits;
  514.     outBits += nBits;
  515.     if (outBits > 8) {
  516.       predLine[k++] = (Guchar)(outBuf >> (outBits - 8));
  517.     }
  518.       }
  519.       if (outBits > 0) {
  520.     predLine[k++] = (Guchar)(outBuf << (8 - outBits));
  521.       }
  522.     }
  523.   }
  524.  
  525.   // reset to start of line
  526.   predIdx = pixBytes;
  527.  
  528.   return gTrue;
  529. }
  530.  
  531. //------------------------------------------------------------------------
  532. // FileStream
  533. //------------------------------------------------------------------------
  534.  
  535. FileStream::FileStream(RFile f1, int start1, int length1, Object *dict1) {
  536.   f = f1;
  537.   start = start1;
  538.   length = length1;
  539.   bufPtr = bufEnd = buf.Ptr();
  540.   bufPos = start;
  541.   savePos = -1;
  542.   dict = *dict1;
  543.   encryption = gFalse;
  544. }
  545.  
  546. FileStream::~FileStream() {
  547.   if (savePos >= 0)
  548.     f.Seek(ESeekStart, savePos);
  549.   dict.free();
  550. }
  551.  
  552. void FileStream::reset() {
  553.   // save current position
  554.   savePos = 0;
  555.   f.Seek(ESeekCurrent, savePos);
  556.   // goto startpos
  557.   f.Seek(ESeekStart, start);
  558.   bufPtr = bufEnd = buf.Ptr();
  559.   bufPos = start;
  560. }
  561.  
  562.  
  563. int FileStream::getChar()
  564.   if (bufPtr<bufEnd)
  565.     return (*bufPtr++ & 0xff);
  566.   if (fillBuf()) 
  567.     return (*bufPtr++ & 0xff); 
  568.   return EOF;
  569.   //return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff); 
  570. }
  571.  
  572. int FileStream::lookChar()
  573.   if (bufPtr<bufEnd)
  574.     return (*bufPtr & 0xff);
  575.   if (fillBuf()) 
  576.     return (*bufPtr & 0xff); 
  577.   return EOF;
  578.   //return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr & 0xff); 
  579. }
  580.  
  581. int FileStream::getPos()
  582.   return bufPos + (bufPtr - buf.Ptr()); 
  583. }
  584.  
  585. GBool FileStream::fillBuf() {
  586.   int n;
  587.  
  588.   bufPos += bufEnd - buf.Ptr();
  589.   bufPtr = bufEnd = buf.Ptr();
  590.   if (length >= 0 && bufPos >= start + length)
  591.     return gFalse;
  592.   if (length >= 0 && bufPos + KBufSize > start + length)
  593.     n = start + length - bufPos;
  594.   else
  595.     n = KBufSize;
  596.   f.Read(buf, n);
  597.   bufEnd = buf.Ptr() + buf.Length();
  598.   if (encryption == gTrue) {
  599.     rc4Crypt(&rc4Key, (unsigned char *)buf.Ptr(), n);
  600.   }
  601.   if (bufPtr >= bufEnd)
  602.     return gFalse;
  603.   return gTrue;
  604. }
  605.  
  606. void FileStream::enableEncryption(RC4KEY *prc4Key)
  607. {
  608.   // prepare RC4 key
  609.   rc4Key = *prc4Key;
  610.   encryption = gTrue;
  611. }
  612.  
  613. void FileStream::setPos(int pos1) {
  614.   int size;
  615.  
  616.   if (pos1 >= 0) {
  617.     f.Seek(ESeekStart, pos1);
  618.     bufPos = pos1;
  619.   } else {
  620.     size = 0;
  621.     f.Seek(ESeekEnd, size);
  622.     if (pos1 < -size)
  623.       pos1 = (int)(-size);
  624.     f.Seek(ESeekEnd, pos1);
  625.     bufPos = 0;
  626.     f.Seek(ESeekCurrent, bufPos);
  627.   }
  628.   bufPtr = bufEnd = buf.Ptr();
  629. }
  630.  
  631. GBool FileStream::checkHeader() {
  632.   char hdrBuf[headerSearchSize+1];
  633.   char *p;
  634.   double version;
  635.   int i;
  636.  
  637.   for (i = 0; i < headerSearchSize; ++i)
  638.     hdrBuf[i] = getChar();
  639.   hdrBuf[headerSearchSize] = '\0';
  640.   for (i = 0; i < headerSearchSize - 5; ++i) {
  641.     if (!strncmp(&hdrBuf[i], "%PDF-", 5))
  642.       break;
  643.   }
  644.   if (i >= headerSearchSize - 5) {
  645.     error(-1, R_MAY_NOT_BE_A_PDF_FILE__CONTINUING_ANYWAY_);
  646.     return gFalse;
  647.   }
  648.   start += i;
  649.   p = strtok(&hdrBuf[i+5], " \t\n\r");
  650.   version = atof(p);
  651.   if (!(hdrBuf[i+5] >= '0' && hdrBuf[i+5] <= '9') ||
  652.       version > pdfVersionNum + 0.0001) {
  653.     error(getPos(), R_PDF_VERSION__S____PDF_SUPPORTS_VERSION__S__CONTINUING_ANYWAY_, 
  654.           p, pdfVersion);
  655.     return gFalse;
  656.   }
  657.   return gTrue;
  658. }
  659.  
  660. Dict *FileStream::getDict()
  661.   return dict.getDict();
  662. }
  663.  
  664. //------------------------------------------------------------------------
  665. // SubStream
  666. //------------------------------------------------------------------------
  667.  
  668. SubStream::SubStream(Stream *str1, Object *dict1) {
  669.   str = str1;
  670.   dict = *dict1;
  671. }
  672.  
  673. SubStream::~SubStream() {
  674.   dict.free();
  675. }
  676.  
  677.  
  678. Dict *SubStream::getDict()
  679.   return dict.getDict(); 
  680. }
  681.  
  682. //------------------------------------------------------------------------
  683. // ASCIIHexStream
  684. //------------------------------------------------------------------------
  685.  
  686. ASCIIHexStream::ASCIIHexStream(Stream *str1) {
  687.   str = str1;
  688.   buf = EOF;
  689.   eof = gFalse;
  690. }
  691.  
  692. ASCIIHexStream::~ASCIIHexStream() {
  693.   delete str;
  694. }
  695.  
  696. void ASCIIHexStream::reset() {
  697.   str->reset();
  698.   buf = EOF;
  699.   eof = gFalse;
  700. }
  701.  
  702. int ASCIIHexStream::lookChar() {
  703.   int c1, c2, x;
  704.  
  705.   if (buf != EOF)
  706.     return buf;
  707.   if (eof) {
  708.     buf = EOF;
  709.     return EOF;
  710.   }
  711.   do {
  712.     c1 = str->getChar();
  713.   } while (isspace(c1));
  714.   if (c1 == '>') {
  715.     eof = gTrue;
  716.     buf = EOF;
  717.     return buf;
  718.   }
  719.   do {
  720.     c2 = str->getChar();
  721.   } while (isspace(c2));
  722.   if (c2 == '>') {
  723.     eof = gTrue;
  724.     c2 = '0';
  725.   }
  726.   if (c1 >= '0' && c1 <= '9') {
  727.     x = (c1 - '0') << 4;
  728.   } else if (c1 >= 'A' && c1 <= 'F') {
  729.     x = (c1 - 'A' + 10) << 4;
  730.   } else if (c1 >= 'a' && c1 <= 'f') {
  731.     x = (c1 - 'a' + 10) << 4;
  732.   } else if (c1 == EOF) {
  733.     eof = gTrue;
  734.     x = 0;
  735.   } else {
  736.     error(getPos(), R_ILLEGAL_CHARACTER___02X__IN_ASCIIHEX_STREAM, c1);
  737.     x = 0;
  738.   }
  739.   if (c2 >= '0' && c2 <= '9') {
  740.     x += c2 - '0';
  741.   } else if (c2 >= 'A' && c2 <= 'F') {
  742.     x += c2 - 'A' + 10;
  743.   } else if (c2 >= 'a' && c2 <= 'f') {
  744.     x += c2 - 'a' + 10;
  745.   } else if (c2 == EOF) {
  746.     eof = gTrue;
  747.     x = 0;
  748.   } else {
  749.     error(getPos(), R_ILLEGAL_CHARACTER___02X__IN_ASCIIHEX_STREAM, c2);
  750.   }
  751.   buf = x & 0xff;
  752.   return buf;
  753. }
  754.  
  755. GString *ASCIIHexStream::getPSFilterL(char *indent) {
  756.   GString *s;
  757.  
  758.   s = str->getPSFilterL(indent);
  759.   s->appendL(indent)->appendL("/ASCIIHexDecode filter\n");
  760.   return s;
  761. }
  762.  
  763. GBool ASCIIHexStream::isBinary(GBool /* last */) {
  764.   return str->isBinary(gFalse);
  765. }
  766.  
  767. //------------------------------------------------------------------------
  768. // ASCII85Stream
  769. //------------------------------------------------------------------------
  770.  
  771. ASCII85Stream::ASCII85Stream(Stream *str1) {
  772.   str = str1;
  773.   index = n = 0;
  774.   eof = gFalse;
  775. }
  776.  
  777. ASCII85Stream::~ASCII85Stream() {
  778.   delete str;
  779. }
  780.  
  781. void ASCII85Stream::reset() {
  782.   str->reset();
  783.   index = n = 0;
  784.   eof = gFalse;
  785. }
  786.  
  787. int ASCII85Stream::lookChar() {
  788.   int k;
  789.   Gulong t;
  790.  
  791.   if (index >= n) {
  792.     if (eof)
  793.       return EOF;
  794.     index = 0;
  795.     do {
  796.       c[0] = str->getChar();
  797.     } while (c[0] == '\n' || c[0] == '\r');
  798.     if (c[0] == '~' || c[0] == EOF) {
  799.       eof = gTrue;
  800.       n = 0;
  801.       return EOF;
  802.     } else if (c[0] == 'z') {
  803.       b[0] = b[1] = b[2] = b[3] = 0;
  804.       n = 4;
  805.     } else {
  806.       for (k = 1; k < 5; ++k) {
  807.     do {
  808.       c[k] = str->getChar();
  809.     } while (c[k] == '\n' || c[k] == '\r');
  810.     if (c[k] == '~' || c[k] == EOF)
  811.       break;
  812.       }
  813.       n = k - 1;
  814.       if (k < 5 && (c[k] == '~' || c[k] == EOF)) {
  815.     for (++k; k < 5; ++k)
  816.       c[k] = 0x21 + 84;
  817.     eof = gTrue;
  818.       }
  819.       t = 0;
  820.       for (k = 0; k < 5; ++k)
  821.     t = t * 85 + (c[k] - 0x21);
  822.       for (k = 3; k >= 0; --k) {
  823.     b[k] = (int)(t & 0xff);
  824.     t >>= 8;
  825.       }
  826.     }
  827.   }
  828.   return b[index];
  829. }
  830.  
  831. GString *ASCII85Stream::getPSFilterL(char *indent) {
  832.   GString *s;
  833.  
  834.   s = str->getPSFilterL(indent);
  835.   s->appendL(indent)->appendL("/ASCII85Decode filter\n");
  836.   return s;
  837. }
  838.  
  839. GBool ASCII85Stream::isBinary(GBool /* last */) {
  840.   return str->isBinary(gFalse);
  841. }
  842.  
  843. //------------------------------------------------------------------------
  844. // LZWStream
  845. //------------------------------------------------------------------------
  846.  
  847. LZWStream::LZWStream(Stream *str1, int early1) {
  848.   str = str1;
  849.   early = early1;
  850.   bufPtr = bufEnd = buf.Ptr();
  851. }
  852.  
  853. void LZWStream::ConstructL(int predictor1, int columns1, int colors1, int bits1)
  854. {
  855.   if (predictor1 != 1) {
  856.     pred = new(ELeave) StreamPredictor(this, predictor1, columns1, colors1, bits1);
  857.     pred->ConstructL();
  858.   } else {
  859.     pred = NULL;
  860.   }
  861.  
  862.   User::LeaveIfError(iZSession.Connect(2));
  863. }
  864.  
  865. LZWStream::~LZWStream() {
  866.   
  867.   if (tName) {
  868.     if (tName->Length() > 0)
  869.       iZSession.Delete(*tName);
  870.     delete tName;
  871.   }
  872.   
  873.   zPipe.Close();
  874.   if (zName.Length() > 0)
  875.     iZSession.Delete(zName);
  876.   iZSession.Close();
  877.  
  878.   delete pred;
  879.   delete str;
  880. }
  881.  
  882. int LZWStream::getChar() {
  883.   if (pred)
  884.     return pred->getChar();
  885.   if (bufPtr<bufEnd)
  886.     return (*bufPtr++ & 0xff);
  887.   if (fillBuf()) 
  888.     return (*bufPtr++ & 0xff); 
  889.   return EOF;
  890.   // return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff);
  891. }
  892.  
  893. int LZWStream::lookChar() {
  894.   if (pred)
  895.     return pred->lookChar();
  896.   if (bufPtr<bufEnd)
  897.     return (*bufPtr & 0xff);
  898.   if (fillBuf()) 
  899.     return (*bufPtr & 0xff); 
  900.   return EOF;
  901.   //return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr & 0xff);
  902. }
  903.  
  904. int LZWStream::getRawChar() {
  905.   if (bufPtr<bufEnd)
  906.     return (*bufPtr++ & 0xff);
  907.   if (fillBuf()) 
  908.     return (*bufPtr++ & 0xff); 
  909.   return EOF;
  910.   //return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff);
  911. }
  912.  
  913. void LZWStream::reset() {
  914.   _LIT(tmpDir, "c:\\system\\temp\\");
  915.  
  916.   RFile f; // compressed file
  917.   CleanupClosePushL(f);
  918.  
  919.   tName = new(ELeave) TFileName();
  920.  
  921.   str->reset();
  922.   bufPtr = bufEnd = buf.Ptr();
  923.  
  924.   // Close compressed file
  925.   zPipe.Close();
  926.   if (zName.Length() > 0) {
  927.     iZSession.Delete(zName);
  928.     zName.Zero();
  929.   }
  930.  
  931.   // create the compressed file, and the temp dir if it doesn't exists
  932.   TInt err = f.Temp(iZSession, tmpDir, *tName, EFileStream);
  933.   if (err == KErrPathNotFound) {
  934.     User::LeaveIfError(iZSession.MkDir(tmpDir));
  935.     User::LeaveIfError(f.Temp(iZSession, tmpDir, *tName, EFileStream));
  936.   }
  937.  
  938.   // now trap all errors to make sure we stay in control; need to remove files
  939.   // in tmpdir if we crash
  940.  
  941.   // fill the compressed file  
  942.   TRAP(err, dumpFile(f));
  943.   
  944.   // create the uncompressed file. Do this here to use as little memory as possible
  945.   // a better solution would be to decompress right out of a memory buffer
  946.   if (err == KErrNone)
  947.     err = zPipe.Temp(iZSession, tmpDir, zName, EFileStream);
  948.   
  949.   // uncompress
  950.   if (err == KErrNone)
  951.     TRAP(err, unlzwL(f, zPipe));
  952.   
  953.   // clear up resources
  954.   CleanupStack::PopAndDestroy(); // f
  955.   iZSession.Delete(*tName);
  956.   delete tName;
  957.   tName = 0;
  958.  
  959.   if (err) {
  960.     zPipe.Close();
  961.     iZSession.Delete(zName);
  962.     zName.Zero();
  963.     error(getPos(), R_COULDN_T_DECOMPRESS_TEMPFILE);
  964.     return;
  965.   }
  966.   
  967.   // Reset for reading
  968.   User::LeaveIfError(zPipe.Flush());
  969.   TInt start=0;
  970.   User::LeaveIfError(zPipe.Seek(ESeekStart, start));
  971.   
  972.   return;
  973. }
  974.  
  975. void LZWStream::dumpFile(RFile f) {
  976.   int outCodeBits;        // size of output code
  977.   int outBits;            // max output code
  978.   int outBuf[8];        // output buffer
  979.   int outData;            // temporary output buffer
  980.   int inCode, outCode;        // input and output codes
  981.   int nextCode;            // next code index
  982.   GBool eof;            // set when EOF is reached
  983.   GBool clear;            // set if table needs to be cleared
  984.   GBool first;            // indicates first code word after clear
  985.   int i, j;
  986.  
  987.   static const TInt KOutMax = 1024;
  988.   // magic number
  989.   TBuf<KOutMax> outBytes(KOutMax);
  990.   outBytes.Zero();
  991.   outBytes.Append(TText8(0x1f));
  992.   outBytes.Append(TText8(0x9d));
  993.  
  994.   // max code length, block mode flag
  995.   outBytes.Append(TText8(0x8c));
  996.  
  997.   // init input side
  998.   inCodeBits = 9;
  999.   inputBuf = 0;
  1000.   inputBits = 0;
  1001.   eof = gFalse;
  1002.  
  1003.   // init output side
  1004.   outCodeBits = 9;
  1005.  
  1006.   // clear table
  1007.   first = gTrue;
  1008.   nextCode = 258;
  1009.  
  1010.   clear = gFalse;
  1011.   do {
  1012.     for (i = 0; i < 8; ++i) {
  1013.       // check for table overflow
  1014.       if (nextCode + early > 0x1001) {
  1015.         inCode = 256;
  1016.  
  1017.       // read input code
  1018.       } else {
  1019.         do {
  1020.           inCode = getCode();
  1021.           if (inCode == EOF) {
  1022.             eof = gTrue;
  1023.             inCode = 0;
  1024.           }
  1025.         } while (first && inCode == 256);
  1026.       }
  1027.  
  1028.       // compute output code
  1029.       if (inCode < 256) {
  1030.         outCode = inCode;
  1031.       } else if (inCode == 256) {
  1032.         outCode = 256;
  1033.         clear = gTrue;
  1034.       } else if (inCode == 257) {
  1035.         outCode = 0;
  1036.         eof = gTrue;
  1037.       } else {
  1038.         outCode = inCode - 1;
  1039.       }
  1040.       outBuf[i] = outCode;
  1041.  
  1042.       // next code index
  1043.       if (first)
  1044.         first = gFalse;
  1045.       else
  1046.         ++nextCode;
  1047.  
  1048.       // check input code size
  1049.       if (nextCode + early == 0x200)
  1050.         inCodeBits = 10;
  1051.       else if (nextCode + early == 0x400) {
  1052.         inCodeBits = 11;
  1053.       } else if (nextCode + early == 0x800) {
  1054.         inCodeBits = 12;
  1055.       }
  1056.  
  1057.       // check for eof/clear
  1058.       if (eof)
  1059.         break;
  1060.       if (clear) {
  1061.         i = 8;
  1062.         break;
  1063.       }
  1064.     }
  1065.  
  1066.     // write output block
  1067.     outData = 0;
  1068.     outBits = 0;
  1069.     j = 0;
  1070.     while (j < i || outBits > 0) {
  1071.       if (outBits < 8 && j < i) {
  1072.         outData = outData | (outBuf[j++] << outBits);
  1073.         outBits += outCodeBits;
  1074.       }
  1075.       // write if buffer full
  1076.       if (outBytes.Length() == KOutMax) {
  1077.         User::LeaveIfError(f.Write(outBytes));
  1078.         outBytes.Zero();
  1079.       }
  1080.       outBytes.Append(TText8(outData & 0xff));
  1081.       outData >>= 8;
  1082.       outBits -= 8;
  1083.     }
  1084.  
  1085.     // check output code size
  1086.     if (nextCode - 1 == 512 ||
  1087.         nextCode - 1 == 1024 ||
  1088.         nextCode - 1 == 2048 ||
  1089.         nextCode - 1 == 4096) {
  1090.       outCodeBits = inCodeBits;
  1091.     }
  1092.  
  1093.     // clear table if necessary
  1094.     if (clear) {
  1095.       inCodeBits = 9;
  1096.       outCodeBits = 9;
  1097.       first = gTrue;
  1098.       nextCode = 258;
  1099.       clear = gFalse;
  1100.     }
  1101.   } while (!eof);
  1102.   
  1103.   // write remains of buffer
  1104.   if (outBytes.Length() > 0)
  1105.     User::LeaveIfError(f.Write(outBytes));
  1106.  
  1107.   User::LeaveIfError(f.Flush());
  1108.   
  1109.   TInt start = 0;
  1110.   User::LeaveIfError(f.Seek(ESeekStart, start));
  1111. }
  1112.  
  1113. int LZWStream::getCode() {
  1114.   int c;
  1115.   int code;
  1116.  
  1117.   while (inputBits < inCodeBits) {
  1118.     if ((c = str->getChar()) == EOF)
  1119.       return EOF;
  1120.     inputBuf = (inputBuf << 8) | (c & 0xff);
  1121.     inputBits += 8;
  1122.   }
  1123.   code = (inputBuf >> (inputBits - inCodeBits)) & ((1 << inCodeBits) - 1);
  1124.   inputBits -= inCodeBits;
  1125.   return code;
  1126. }
  1127.  
  1128. GBool LZWStream::fillBuf() {
  1129.  
  1130.   if (zName.Length() == 0)
  1131.     return gFalse;
  1132.   User::LeaveIfError(zPipe.Read(buf, 256));
  1133.   if (buf.Length() < 256) {
  1134.     zPipe.Close();
  1135.     iZSession.Delete(zName);
  1136.     zName.Zero();
  1137.   }
  1138.   bufPtr = buf.Ptr();
  1139.   bufEnd = buf.Ptr() + buf.Length();
  1140.   return buf.Length() > 0;
  1141. }
  1142.  
  1143. GString *LZWStream::getPSFilterL(char *indent) {
  1144.   GString *s;
  1145.  
  1146.   if (pred) {
  1147.     return NULL;
  1148.   }
  1149.   s = str->getPSFilterL(indent);
  1150.   s->appendL(indent)->appendL("/LZWDecode filter\n");
  1151.   return s;
  1152. }
  1153.  
  1154. GBool LZWStream::isBinary(GBool /* last */) {
  1155.   return str->isBinary(gTrue);
  1156. }
  1157.  
  1158. //------------------------------------------------------------------------
  1159. // RunLengthStream
  1160. //------------------------------------------------------------------------
  1161.  
  1162. RunLengthStream::RunLengthStream(Stream *str1) {
  1163.   str = str1;
  1164.   bufPtr = bufEnd = buf;
  1165.   eof = gFalse;
  1166. }
  1167.  
  1168. RunLengthStream::~RunLengthStream() {
  1169.   delete str;
  1170. }
  1171.  
  1172. void RunLengthStream::reset() {
  1173.   str->reset();
  1174.   bufPtr = bufEnd = buf;
  1175.   eof = gFalse;
  1176. }
  1177.  
  1178. GString *RunLengthStream::getPSFilterL(char *indent) {
  1179.   GString *s;
  1180.  
  1181.   s = str->getPSFilterL(indent);
  1182.   s->appendL(indent)->appendL("/RunLengthDecode filter\n");
  1183.   return s;
  1184. }
  1185.  
  1186. GBool RunLengthStream::isBinary(GBool /* last */) {
  1187.   return str->isBinary(gTrue);
  1188. }
  1189.  
  1190. #if 0
  1191. int RunLengthStream::getChar() { 
  1192.   if (bufPtr<bufEnd)
  1193.     return (*bufPtr++ & 0xff);
  1194.   if (fillBuf()) 
  1195.     return (*bufPtr++ & 0xff); 
  1196.   return EOF;
  1197.   //return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff); 
  1198.   //return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff); 
  1199. }
  1200.  
  1201. int RunLengthStream::lookChar() {
  1202.   if (bufPtr<bufEnd)
  1203.     return (*bufPtr & 0xff);
  1204.   if (fillBuf()) 
  1205.     return (*bufPtr & 0xff); 
  1206.   return EOF;
  1207.   //return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff); 
  1208.   //return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr & 0xff); 
  1209. }
  1210. #endif
  1211.  
  1212. GBool RunLengthStream::fillBuf() {
  1213.   register int c;
  1214.   register int n, i;
  1215.  
  1216.   if (eof)
  1217.     return gFalse;
  1218.   c = str->getChar();
  1219.   if (c == 0x80 || c == EOF) {
  1220.     eof = gTrue;
  1221.     return gFalse;
  1222.   }
  1223.   if (c < 0x80) {
  1224.     n = c + 1;
  1225.     for (i = 0; i < n; ++i)
  1226.       buf[i] = (char)str->getChar();
  1227.   } else {
  1228.     n = 0x101 - c;
  1229.     c = str->getChar();
  1230.     for (i = 0; i < n; ++i)
  1231.       buf[i] = (char)c;
  1232.   }
  1233.   bufPtr = buf;
  1234.   bufEnd = buf + n;
  1235.   return gTrue;
  1236. }
  1237.  
  1238. //------------------------------------------------------------------------
  1239. // CCITTFaxStream
  1240. //------------------------------------------------------------------------
  1241.  
  1242. CCITTFaxStream::CCITTFaxStream(Stream *str, int encoding, GBool endOfLine,
  1243.                    GBool byteAlign, int columns, int rows,
  1244.                    GBool endOfBlock, GBool black) {
  1245.   this->str = str;
  1246.   this->encoding = encoding;
  1247.   this->endOfLine = endOfLine;
  1248.   this->byteAlign = byteAlign;
  1249.   this->columns = columns;
  1250.   this->rows = rows;
  1251.   this->endOfBlock = endOfBlock;
  1252.   this->black = black;
  1253. }
  1254.  
  1255. void CCITTFaxStream::ConstructL()
  1256. {
  1257.   refLine = (short *)User::AllocL((columns + 3) * sizeof(short));
  1258.   codingLine = (short *)User::AllocL((columns + 2) * sizeof(short));
  1259.  
  1260.   eof = gFalse;
  1261.   row = 0;
  1262.   nextLine2D = encoding < 0;
  1263.   inputBits = 0;
  1264.   codingLine[0] = 0;
  1265.   codingLine[1] = refLine[2] = columns;
  1266.   a0 = 1;
  1267.  
  1268.   buf = EOF;
  1269. }
  1270.  
  1271. CCITTFaxStream::~CCITTFaxStream() {
  1272.   delete str;
  1273.   User::Free(refLine);
  1274.   User::Free(codingLine);
  1275. }
  1276.  
  1277. void CCITTFaxStream::reset() {
  1278.   int n;
  1279.  
  1280.   str->reset();
  1281.   eof = gFalse;
  1282.   row = 0;
  1283.   nextLine2D = encoding < 0;
  1284.   inputBits = 0;
  1285.   codingLine[0] = 0;
  1286.   codingLine[1] = refLine[2] = columns;
  1287.   a0 = 1;
  1288.   buf = EOF;
  1289.  
  1290.   // get initial end-of-line marker and 2D encoding tag
  1291.   if (endOfBlock) {
  1292.     if (lookBits(12) == 0x001) {
  1293.       eatBits(12);
  1294.     }
  1295.   } else {
  1296.     for (n = 0; n < 11 && lookBits(n) == 0; ++n) ;
  1297.     if (n == 11 && lookBits(12) == 0x001) {
  1298.       eatBits(12);
  1299.     }
  1300.   }
  1301.   if (encoding > 0) {
  1302.     nextLine2D = !lookBits(1);
  1303.     eatBits(1);
  1304.   }
  1305. }
  1306.  
  1307. int CCITTFaxStream::lookChar() {
  1308.   short code1, code2, code3;
  1309.   int a0New;
  1310. #if 0 //~
  1311.   GBool err;
  1312. #endif
  1313.   int ret;
  1314.   int bits, i, n;
  1315.  
  1316.   // if at eof just return EOF
  1317.   if (eof && codingLine[a0] >= columns) {
  1318.     return EOF;
  1319.   }
  1320.  
  1321.   // read the next row
  1322. #if 0 //~
  1323.   err = gFalse;
  1324. #endif
  1325.   if (codingLine[a0] >= columns) {
  1326.  
  1327.     // 2-D encoding
  1328.     if (nextLine2D) {
  1329.       for (i = 0; codingLine[i] < columns; ++i)
  1330.     refLine[i] = codingLine[i];
  1331.       refLine[i] = refLine[i + 1] = columns;
  1332.       b1 = 1;
  1333.       a0New = codingLine[a0 = 0] = 0;
  1334.       do {
  1335.     code1 = getTwoDimCode();
  1336.     switch (code1) {
  1337.     case twoDimPass:
  1338.       if (refLine[b1] < columns) {
  1339.         a0New = refLine[b1 + 1];
  1340.         b1 += 2;
  1341.       }
  1342.       break;
  1343.     case twoDimHoriz:
  1344.       if ((a0 & 1) == 0) {
  1345.         code1 = code2 = 0;
  1346.         do {
  1347.           code1 += code3 = getWhiteCode();
  1348.         } while (code3 >= 64);
  1349.         do {
  1350.           code2 += code3 = getBlackCode();
  1351.         } while (code3 >= 64);
  1352.       } else {
  1353.         code1 = code2 = 0;
  1354.         do {
  1355.           code1 += code3 = getBlackCode();
  1356.         } while (code3 >= 64);
  1357.         do {
  1358.           code2 += code3 = getWhiteCode();
  1359.         } while (code3 >= 64);
  1360.       }
  1361.       codingLine[a0 + 1] = a0New + code1;
  1362.       ++a0;
  1363.       a0New = codingLine[a0 + 1] = codingLine[a0] + code2;
  1364.       ++a0;
  1365.       while (refLine[b1] <= codingLine[a0] && refLine[b1] < columns)
  1366.         b1 += 2;
  1367.       break;
  1368.     case twoDimVert0:
  1369.       a0New = codingLine[++a0] = refLine[b1];
  1370.       if (refLine[b1] < columns) {
  1371.         ++b1;
  1372.         while (refLine[b1] <= codingLine[a0] && refLine[b1] < columns)
  1373.           b1 += 2;
  1374.       }
  1375.       break;
  1376.     case twoDimVertR1:
  1377.       a0New = codingLine[++a0] = refLine[b1] + 1;
  1378.       if (refLine[b1] < columns) {
  1379.         ++b1;
  1380.         while (refLine[b1] <= codingLine[a0] && refLine[b1] < columns)
  1381.           b1 += 2;
  1382.       }
  1383.       break;
  1384.     case twoDimVertL1:
  1385.       a0New = codingLine[++a0] = refLine[b1] - 1;
  1386.       --b1;
  1387.       while (refLine[b1] <= codingLine[a0] && refLine[b1] < columns)
  1388.         b1 += 2;
  1389.       break;
  1390.     case twoDimVertR2:
  1391.       a0New = codingLine[++a0] = refLine[b1] + 2;
  1392.       if (refLine[b1] < columns) {
  1393.         ++b1;
  1394.         while (refLine[b1] <= codingLine[a0] && refLine[b1] < columns)
  1395.           b1 += 2;
  1396.       }
  1397.       break;
  1398.     case twoDimVertL2:
  1399.       a0New = codingLine[++a0] = refLine[b1] - 2;
  1400.       --b1;
  1401.       while (refLine[b1] <= codingLine[a0] && refLine[b1] < columns)
  1402.         b1 += 2;
  1403.       break;
  1404.     case twoDimVertR3:
  1405.       a0New = codingLine[++a0] = refLine[b1] + 3;
  1406.       if (refLine[b1] < columns) {
  1407.         ++b1;
  1408.         while (refLine[b1] <= codingLine[a0] && refLine[b1] < columns)
  1409.           b1 += 2;
  1410.       }
  1411.       break;
  1412.     case twoDimVertL3:
  1413.       a0New = codingLine[++a0] = refLine[b1] - 3;
  1414.       --b1;
  1415.       while (refLine[b1] <= codingLine[a0] && refLine[b1] < columns)
  1416.         b1 += 2;
  1417.       break;
  1418.     case EOF:
  1419.       eof = gTrue;
  1420.       codingLine[a0 = 0] = columns;
  1421.       return EOF;
  1422.     default:
  1423.       error(getPos(), R_BAD_2D_CODE__04X_IN_CCITTFAX_STREAM, code1);
  1424. #if 0 //~
  1425.       err = gTrue;
  1426.       break;
  1427. #else
  1428.       eof = gTrue;
  1429.       return EOF;
  1430. #endif
  1431.     }
  1432.       } while (codingLine[a0] < columns);
  1433.  
  1434.     // 1-D encoding
  1435.     } else {
  1436.       codingLine[a0 = 0] = 0;
  1437.       for (;;) {
  1438.     code1 = 0;
  1439.     do {
  1440.       code1 += code3 = getWhiteCode();
  1441.     } while (code3 >= 64);
  1442.     codingLine[a0+1] = codingLine[a0] + code1;
  1443.     ++a0;
  1444.     if (codingLine[a0] >= columns)
  1445.       break;
  1446.     code2 = 0;
  1447.     do {
  1448.       code2 += code3 = getBlackCode();
  1449.     } while (code3 >= 64);
  1450.     codingLine[a0+1] = codingLine[a0] + code2;
  1451.     ++a0;
  1452.     if (codingLine[a0] >= columns)
  1453.       break;
  1454.       }
  1455.     }
  1456.  
  1457.     if (codingLine[a0] != columns) {
  1458.       error(getPos(), R_CCITTFAX_ROW_IS_WRONG_LENGTH___D_, codingLine[a0]);
  1459. #if 0 //~
  1460.       err = gTrue;
  1461. #endif
  1462.     }
  1463.  
  1464.     // byte-align the row
  1465.     if (byteAlign) {
  1466.       inputBits &= ~7;
  1467.     }
  1468.  
  1469.     // check for end-of-line marker, end-of-block marker, and
  1470.     // 2D encoding tag
  1471.     if (endOfBlock) {
  1472.       code1 = lookBits(12);
  1473.       if (code1 == EOF) {
  1474.     eof = gTrue;
  1475.       } else if (code1 == 0x001) {
  1476.     eatBits(12);
  1477.     if (encoding > 0) {
  1478.       nextLine2D = !lookBits(1);
  1479.       eatBits(1);
  1480.     }
  1481.     code1 = lookBits(12);
  1482.     if (code1 == 0x001) {
  1483.       eatBits(12);
  1484.       if (encoding > 0) {
  1485.         lookBits(1);
  1486.         eatBits(1);
  1487.       }
  1488.       if (encoding >= 0) {
  1489.         for (i = 0; i < 4; ++i) {
  1490.           code1 = lookBits(12);
  1491.           if (code1 != 0x001) {
  1492.         error(getPos(), R_BAD_RTC_CODE_IN_CCITTFAX_STREAM);
  1493.           }
  1494.           eatBits(12);
  1495.           if (encoding > 0) {
  1496.         lookBits(1);
  1497.         eatBits(1);
  1498.           }
  1499.         }
  1500.       }
  1501.       eof = gTrue;
  1502.     }
  1503.       } else {
  1504.     if (encoding > 0) {
  1505.       nextLine2D = !lookBits(1);
  1506.       eatBits(1);
  1507.     }
  1508.       }
  1509.     } else {
  1510.       if (row == rows - 1) {
  1511.     eof = gTrue;
  1512.       } else {
  1513.     for (n = 0; n < 11 && lookBits(n) == 0; ++n) ;
  1514.     if (n == 11 && lookBits(12) == 0x001) {
  1515.       eatBits(12);
  1516.     }
  1517.     if (encoding > 0) {
  1518.       nextLine2D = !lookBits(1);
  1519.       eatBits(1);
  1520.     }
  1521.       }
  1522.     }
  1523.  
  1524. #if 0 //~
  1525.     // This looks for an end-of-line marker after an error, however
  1526.     // some (most?) CCITT streams in PDF files don't use end-of-line
  1527.     // markers, and the just-plow-on technique works better in those
  1528.     // cases.
  1529.     else if (err) {
  1530.       do {
  1531.     if (code1 == EOF) {
  1532.       eof = gTrue;
  1533.       return EOF;
  1534.     }
  1535.     eatBits(1);
  1536.     code1 = look13Bits();
  1537.       } while ((code1 >> 1) != 0x001);
  1538.       eatBits(12); 
  1539.       codingLine[++a0] = columns;
  1540.       if (encoding > 0) {
  1541.     eatBits(1);
  1542.     nextLine2D = !(code1 & 1);
  1543.       }
  1544.     }
  1545. #endif
  1546.  
  1547.     a0 = 0;
  1548.     outputBits = codingLine[1] - codingLine[0];
  1549.     if (outputBits == 0) {
  1550.       a0 = 1;
  1551.       outputBits = codingLine[2] - codingLine[1];
  1552.     }
  1553.  
  1554.     ++row;
  1555.   }
  1556.  
  1557.   // get a byte
  1558.   if (outputBits >= 8) {
  1559.     ret = ((a0 & 1) == 0) ? 0xff : 0x00;
  1560.     if ((outputBits -= 8) == 0) {
  1561.       ++a0;
  1562.       if (codingLine[a0] < columns) {
  1563.     outputBits = codingLine[a0 + 1] - codingLine[a0];
  1564.       }
  1565.     }
  1566.   } else {
  1567.     bits = 8;
  1568.     ret = 0;
  1569.     do {
  1570.       if (outputBits > bits) {
  1571.     i = bits;
  1572.     bits = 0;
  1573.     if ((a0 & 1) == 0) {
  1574.       ret |= 0xff >> (8 - i);
  1575.     }
  1576.     outputBits -= i;
  1577.       } else {
  1578.     i = outputBits;
  1579.     bits -= outputBits;
  1580.     if ((a0 & 1) == 0) {
  1581.       ret |= (0xff >> (8 - i)) << bits;
  1582.     }
  1583.     outputBits = 0;
  1584.     ++a0;
  1585.     if (codingLine[a0] < columns) {
  1586.       outputBits = codingLine[a0 + 1] - codingLine[a0];
  1587.     }
  1588.       }
  1589.     } while (bits > 0 && codingLine[a0] < columns);
  1590.   }
  1591.   buf = black ? (ret ^ 0xff) : ret;
  1592.   return buf;
  1593. }
  1594.  
  1595. short CCITTFaxStream::getTwoDimCode() {
  1596.   short code;
  1597.   const CCITTCode *p;
  1598.   int n;
  1599.  
  1600.   code = 0; // make gcc happy
  1601.   if (endOfBlock) {
  1602.     code = lookBits(7);
  1603.     p = &twoDimTab1[code];
  1604.     if (p->bits > 0) {
  1605.       eatBits(p->bits);
  1606.       return p->n;
  1607.     }
  1608.   } else {
  1609.     for (n = 1; n <= 7; ++n) {
  1610.       code = lookBits(n);
  1611.       if (n < 7) {
  1612.     code <<= 7 - n;
  1613.       }
  1614.       p = &twoDimTab1[code];
  1615.       if (p->bits == n) {
  1616.     eatBits(n);
  1617.     return p->n;
  1618.       }
  1619.     }
  1620.   }
  1621.   error(getPos(), R_BAD_TWO_DIM_CODE___04X__IN_CCITTFAX_STREAM, code);
  1622.   return EOF;
  1623. }
  1624.  
  1625. short CCITTFaxStream::getWhiteCode() {
  1626.   short code;
  1627.   const CCITTCode *p;
  1628.   int n;
  1629.  
  1630.   code = 0; // make gcc happy
  1631.   if (endOfBlock) {
  1632.     code = lookBits(12);
  1633.     if ((code >> 5) == 0)
  1634.       p = &whiteTab1[code];
  1635.     else
  1636.       p = &whiteTab2[code >> 3];
  1637.     if (p->bits > 0) {
  1638.       eatBits(p->bits);
  1639.       return p->n;
  1640.     }
  1641.   } else {
  1642.     for (n = 1; n <= 9; ++n) {
  1643.       code = lookBits(n);
  1644.       if (n < 9) {
  1645.     code <<= 9 - n;
  1646.       }
  1647.       p = &whiteTab2[code];
  1648.       if (p->bits == n) {
  1649.     eatBits(n);
  1650.     return p->n;
  1651.       }
  1652.     }
  1653.     for (n = 11; n <= 12; ++n) {
  1654.       code = lookBits(n);
  1655.       if (n < 12) {
  1656.     code <<= 12 - n;
  1657.       }
  1658.       p = &whiteTab1[code];
  1659.       if (p->bits == n) {
  1660.     eatBits(n);
  1661.     return p->n;
  1662.       }
  1663.     }
  1664.   }
  1665.   error(getPos(), R_BAD_WHITE_CODE___04X__IN_CCITTFAX_STREAM, code);
  1666.   return EOF;
  1667. }
  1668.  
  1669. short CCITTFaxStream::getBlackCode() {
  1670.   short code;
  1671.   const CCITTCode *p;
  1672.   int n;
  1673.  
  1674.   code = 0; // make gcc happy
  1675.   if (endOfBlock) {
  1676.     code = lookBits(13);
  1677.     if ((code >> 7) == 0)
  1678.       p = &blackTab1[code];
  1679.     else if ((code >> 9) == 0)
  1680.       p = &blackTab2[(code >> 1) - 64];
  1681.     else
  1682.       p = &blackTab3[code >> 7];
  1683.     if (p->bits > 0) {
  1684.       eatBits(p->bits);
  1685.       return p->n;
  1686.     }
  1687.   } else {
  1688.     for (n = 2; n <= 6; ++n) {
  1689.       code = lookBits(n);
  1690.       if (n < 6) {
  1691.     code <<= 6 - n;
  1692.       }
  1693.       p = &blackTab3[code];
  1694.       if (p->bits == n) {
  1695.     eatBits(n);
  1696.     return p->n;
  1697.       }
  1698.     }
  1699.     for (n = 7; n <= 12; ++n) {
  1700.       code = lookBits(n);
  1701.       if (n < 12) {
  1702.     code <<= 12 - n;
  1703.       }
  1704.       if (code >= 64) {
  1705.     p = &blackTab2[code - 64];
  1706.     if (p->bits == n) {
  1707.       eatBits(n);
  1708.       return p->n;
  1709.     }
  1710.       }
  1711.     }
  1712.     for (n = 10; n <= 13; ++n) {
  1713.       code = lookBits(n);
  1714.       if (n < 13) {
  1715.     code <<= 13 - n;
  1716.       }
  1717.       p = &blackTab1[code];
  1718.       if (p->bits == n) {
  1719.     eatBits(n);
  1720.     return p->n;
  1721.       }
  1722.     }
  1723.   }
  1724.   error(getPos(), R_BAD_BLACK_CODE___04X__IN_CCITTFAX_STREAM, code);
  1725.   return EOF;
  1726. }
  1727.  
  1728. short CCITTFaxStream::lookBits(int n) {
  1729.   int c;
  1730.  
  1731.   while (inputBits < n) {
  1732.     if ((c = str->getChar()) == EOF) {
  1733.       if (inputBits == 0)
  1734.     return EOF;
  1735.       c = 0;
  1736.     }
  1737.     inputBuf = (inputBuf << 8) + c;
  1738.     inputBits += 8;
  1739.   }
  1740.   return (inputBuf >> (inputBits - n)) & (0xffff >> (16 - n));
  1741. }
  1742.  
  1743. GString *CCITTFaxStream::getPSFilterL(char *indent) {
  1744.   GString *s;
  1745.   char s1[50];
  1746.  
  1747.   s = str->getPSFilterL(indent);
  1748.   s->appendL(indent)->appendL("<< ");
  1749.   if (encoding != 0) {
  1750.     sprintf(s1, "/K %d ", encoding);
  1751.     s->appendL(s1);
  1752.   }
  1753.   if (endOfLine) {
  1754.     s->appendL("/EndOfLine true ");
  1755.   }
  1756.   if (byteAlign) {
  1757.     s->appendL("/EncodedByteAlign true ");
  1758.   }
  1759.   sprintf(s1, "/Columns %d ", columns);
  1760.   s->appendL(s1);
  1761.   if (rows != 0) {
  1762.     sprintf(s1, "/Rows %d ", rows);
  1763.     s->appendL(s1);
  1764.   }
  1765.   if (!endOfBlock) {
  1766.     s->appendL("/EndOfBlock false ");
  1767.   }
  1768.   if (black) {
  1769.     s->appendL("/BlackIs1 true ");
  1770.   }
  1771.   s->appendL(">> /CCITTFaxDecode filter\n");
  1772.   return s;
  1773. }
  1774.  
  1775. GBool CCITTFaxStream::isBinary(GBool /* last */) {
  1776.   return str->isBinary(gTrue);
  1777. }
  1778.  
  1779. //------------------------------------------------------------------------
  1780. // DCTStream
  1781. //------------------------------------------------------------------------
  1782.  
  1783. // IDCT constants (20.12 fixed point format)
  1784. #ifndef FP_IDCT
  1785. #define dctCos1    4017        // cos(pi/16)
  1786. #define dctSin1     799        // sin(pi/16)
  1787. #define dctCos3    3406        // cos(3*pi/16)
  1788. #define dctSin3    2276        // sin(3*pi/16)
  1789. #define dctCos6    1567        // cos(6*pi/16)
  1790. #define dctSin6    3784        // sin(6*pi/16)
  1791. #define dctSqrt2   5793        // sqrt(2)
  1792. #define dctSqrt1d2 2896        // sqrt(2) / 2
  1793. #endif
  1794.  
  1795. // IDCT constants
  1796. #ifdef FP_IDCT
  1797. #define dctCos1    0.98078528    // cos(pi/16)
  1798. #define dctSin1    0.19509032    // sin(pi/16)
  1799. #define dctCos3    0.83146961    // cos(3*pi/16)
  1800. #define dctSin3    0.55557023    // sin(3*pi/16)
  1801. #define dctCos6    0.38268343    // cos(6*pi/16)
  1802. #define dctSin6    0.92387953    // sin(6*pi/16)
  1803. #define dctSqrt2   1.41421356    // sqrt(2)
  1804. #define dctSqrt1d2 0.70710678    // sqrt(2) / 2
  1805. #endif
  1806.  
  1807. // color conversion parameters (16.16 fixed point format)
  1808. #define dctCrToR   91881    //  1.4020
  1809. #define dctCbToG  -22553    // -0.3441363
  1810. #define dctCrToG  -46802    // -0.71413636
  1811. #define dctCbToB  116130    //  1.772
  1812.  
  1813. // clip [-256,511] --> [0,255]
  1814. #define dctClipOffset 256
  1815.  
  1816. #ifndef __SYMBIAN32__
  1817. static Guchar dctClip[768];
  1818. static int dctClipInit = 0;
  1819. #endif
  1820.  
  1821. // zig zag decode map
  1822. static const int dctZigZag[64] = {
  1823.    0,
  1824.    1,  8,
  1825.   16,  9,  2,
  1826.    3, 10, 17, 24,
  1827.   32, 25, 18, 11, 4,
  1828.    5, 12, 19, 26, 33, 40,
  1829.   48, 41, 34, 27, 20, 13,  6,
  1830.    7, 14, 21, 28, 35, 42, 49, 56,
  1831.   57, 50, 43, 36, 29, 22, 15,
  1832.   23, 30, 37, 44, 51, 58,
  1833.   59, 52, 45, 38, 31,
  1834.   39, 46, 53, 60,
  1835.   61, 54, 47,
  1836.   55, 62,
  1837.   63
  1838. };
  1839.  
  1840. #ifdef __SYMBIAN32__
  1841. #undef FP_IDCT
  1842. #endif
  1843.  
  1844. DCTStream::DCTStream(Stream *str1) {
  1845.   int i, j;
  1846.  
  1847.   str = str1;
  1848.   width = height = 0;
  1849.   mcuWidth = mcuHeight = 0;
  1850.   numComps = 0;
  1851.   comp = 0;
  1852.   x = y = dy = 0;
  1853.   for (i = 0; i < 4; ++i)
  1854.     for (j = 0; j < 32; ++j)
  1855.       rowBuf[i][j] = NULL;
  1856.  
  1857. #ifdef __SYMBIAN32__
  1858.   // the this->dctClip table is always initialised 
  1859.   dctClipInit=0;
  1860. #endif
  1861.  
  1862.   if (!dctClipInit) {
  1863.     for (i = -256; i < 0; ++i)
  1864.       dctClip[dctClipOffset + i] = 0;
  1865.     for (i = 0; i < 256; ++i)
  1866.       dctClip[dctClipOffset + i] = i;
  1867.     for (i = 256; i < 512; ++i)
  1868.       dctClip[dctClipOffset + i] = 255;
  1869.     dctClipInit = 1;
  1870.   }
  1871. }
  1872.  
  1873. DCTStream::~DCTStream() {
  1874.   int i, j;
  1875.  
  1876.   delete str;
  1877.   for (i = 0; i < numComps; ++i)
  1878.     for (j = 0; j < mcuHeight; ++j)
  1879.       User::Free(rowBuf[i][j]);
  1880. }
  1881.  
  1882. void DCTStream::reset() {
  1883.   str->reset();
  1884.   if (!readHeaderL()) {
  1885.     y = height;
  1886.     return;
  1887.   }
  1888.   restartMarker = 0xd0;
  1889.   restart();
  1890. }
  1891.  
  1892. int DCTStream::getChar() {
  1893.   int c;
  1894.  
  1895.   c = lookChar();
  1896.   if (c == EOF)
  1897.     return EOF;
  1898.   if (++comp == numComps) {
  1899.     comp = 0;
  1900.     if (++x == width) {
  1901.       x = 0;
  1902.       ++y;
  1903.       ++dy;
  1904.     }
  1905.   }
  1906.   if (y == height)
  1907.     readTrailer();
  1908.   return c;
  1909. }
  1910.  
  1911. int DCTStream::lookChar() {
  1912.   if (y >= height)
  1913.     return EOF;
  1914.   if (dy >= mcuHeight) {
  1915.     if (!readMCURow()) {
  1916.       y = height;
  1917.       return EOF;
  1918.     }
  1919.     comp = 0;
  1920.     x = 0;
  1921.     dy = 0;
  1922.   }
  1923.   return rowBuf[comp][dy][x];
  1924. }
  1925.  
  1926. void DCTStream::restart() {
  1927.   int i;
  1928.  
  1929.   inputBits = 0;
  1930.   restartCtr = restartInterval;
  1931.   for (i = 0; i < numComps; ++i)
  1932.     compInfo[i].prevDC = 0;
  1933. }
  1934.  
  1935. GBool DCTStream::readMCURow() {
  1936.   Guchar data[64];
  1937.   Guchar *p1, *p2;
  1938.   int pY, pCb, pCr, pR, pG, pB;
  1939.   int h, v, horiz, vert, hSub, vSub;
  1940.   int x1, x2, y2, x3, y3, x4, y4, x5, y5, cc, i;
  1941.   int c;
  1942.  
  1943.   for (x1 = 0; x1 < width; x1 += mcuWidth) {
  1944.  
  1945.     // deal with restart marker
  1946.     if (restartInterval > 0 && restartCtr == 0) {
  1947.       c = readMarker();
  1948.       if (c != restartMarker) {
  1949.     error(getPos(), R_BAD_DCT_DATA__INCORRECT_RESTART_MARKER);
  1950.     return gFalse;
  1951.       }
  1952.       if (++restartMarker == 0xd8)
  1953.     restartMarker = 0xd0;
  1954.       restart();
  1955.     }
  1956.  
  1957.     // read one MCU
  1958.     for (cc = 0; cc < numComps; ++cc) {
  1959.       h = compInfo[cc].hSample;
  1960.       v = compInfo[cc].vSample;
  1961.       horiz = mcuWidth / h;
  1962.       vert = mcuHeight / v;
  1963.       hSub = horiz / 8;
  1964.       vSub = vert / 8;
  1965.       for (y2 = 0; y2 < mcuHeight; y2 += vert) {
  1966.     for (x2 = 0; x2 < mcuWidth; x2 += horiz) {
  1967.       if (!readDataUnit(&dcHuffTables[compInfo[cc].dcHuffTable],
  1968.                 &acHuffTables[compInfo[cc].acHuffTable],
  1969.                 quantTables[compInfo[cc].quantTable],
  1970.                 &compInfo[cc].prevDC,
  1971.                 data))
  1972.         return gFalse;
  1973.       if (hSub == 1 && vSub == 1) {
  1974.         for (y3 = 0, i = 0; y3 < 8; ++y3, i += 8) {
  1975.           p1 = &rowBuf[cc][y2+y3][x1+x2];
  1976.           p1[0] = data[i];
  1977.           p1[1] = data[i+1];
  1978.           p1[2] = data[i+2];
  1979.           p1[3] = data[i+3];
  1980.           p1[4] = data[i+4];
  1981.           p1[5] = data[i+5];
  1982.           p1[6] = data[i+6];
  1983.           p1[7] = data[i+7];
  1984.         }
  1985.       } else if (hSub == 2 && vSub == 2) {
  1986.         for (y3 = 0, i = 0; y3 < 16; y3 += 2, i += 8) {
  1987.           p1 = &rowBuf[cc][y2+y3][x1+x2];
  1988.           p2 = &rowBuf[cc][y2+y3+1][x1+x2];
  1989.           p1[0] = p1[1] = p2[0] = p2[1] = data[i];
  1990.           p1[2] = p1[3] = p2[2] = p2[3] = data[i+1];
  1991.           p1[4] = p1[5] = p2[4] = p2[5] = data[i+2];
  1992.           p1[6] = p1[7] = p2[6] = p2[7] = data[i+3];
  1993.           p1[8] = p1[9] = p2[8] = p2[9] = data[i+4];
  1994.           p1[10] = p1[11] = p2[10] = p2[11] = data[i+5];
  1995.           p1[12] = p1[13] = p2[12] = p2[13] = data[i+6];
  1996.           p1[14] = p1[15] = p2[14] = p2[15] = data[i+7];
  1997.         }
  1998.       } else {
  1999.         i = 0;
  2000.         for (y3 = 0, y4 = 0; y3 < 8; ++y3, y4 += vSub) {
  2001.           for (x3 = 0, x4 = 0; x3 < 8; ++x3, x4 += hSub) {
  2002.         for (y5 = 0; y5 < vSub; ++y5)
  2003.           for (x5 = 0; x5 < hSub; ++x5)
  2004.             rowBuf[cc][y2+y4+y5][x1+x2+x4+x5] = data[i];
  2005.         ++i;
  2006.           }
  2007.         }
  2008.       }
  2009.     }
  2010.       }
  2011.     }
  2012.     --restartCtr;
  2013.  
  2014.     // color space conversion
  2015.     if (colorXform) {
  2016.       // convert YCbCr to RGB
  2017.       if (numComps == 3) {
  2018.     for (y2 = 0; y2 < mcuHeight; ++y2) {
  2019.       for (x2 = 0; x2 < mcuWidth; ++x2) {
  2020.         pY = rowBuf[0][y2][x1+x2];
  2021.         pCb = rowBuf[1][y2][x1+x2] - 128;
  2022.         pCr = rowBuf[2][y2][x1+x2] - 128;
  2023.         pR = ((pY << 16) + dctCrToR * pCr + 32768) >> 16;
  2024.         rowBuf[0][y2][x1+x2] = dctClip[dctClipOffset + pR];
  2025.         pG = ((pY << 16) + dctCbToG * pCb + dctCrToG * pCr + 32768) >> 16;
  2026.         rowBuf[1][y2][x1+x2] = dctClip[dctClipOffset + pG];
  2027.         pB = ((pY << 16) + dctCbToB * pCb + 32768) >> 16;
  2028.         rowBuf[2][y2][x1+x2] = dctClip[dctClipOffset + pB];
  2029.       }
  2030.     }
  2031.       // convert YCbCrK to CMYK (K is passed through unchanged)
  2032.       } else if (numComps == 4) {
  2033.     for (y2 = 0; y2 < mcuHeight; ++y2) {
  2034.       for (x2 = 0; x2 < mcuWidth; ++x2) {
  2035.         pY = rowBuf[0][y2][x1+x2];
  2036.         pCb = rowBuf[1][y2][x1+x2] - 128;
  2037.         pCr = rowBuf[2][y2][x1+x2] - 128;
  2038.         pR = ((pY << 16) + dctCrToR * pCr + 32768) >> 16;
  2039.         rowBuf[0][y2][x1+x2] = 255 - dctClip[dctClipOffset + pR];
  2040.         pG = ((pY << 16) + dctCbToG * pCb + dctCrToG * pCr + 32678) >> 16;
  2041.         rowBuf[1][y2][x1+x2] = 255 - dctClip[dctClipOffset + pG];
  2042.         pB = ((pY << 16) + dctCbToB * pCb + 32768) >> 16;
  2043.         rowBuf[2][y2][x1+x2] = 255 - dctClip[dctClipOffset + pB];
  2044.       }
  2045.     }
  2046.       }
  2047.     }
  2048.   }
  2049.   return gTrue;
  2050. }
  2051.  
  2052. // This IDCT algorithm is taken from:
  2053. //   Christoph Loeffler, Adriaan Ligtenberg, George S. Moschytz,
  2054. //   "Practical Fast 1-D DCT Algorithms with 11 Multiplications",
  2055. //   IEEE Intl. Conf. on Acoustics, Speech & Signal Processing, 1989,
  2056. //   988-991.
  2057. // The stage numbers mentioned in the comments refer to Figure 1 in this
  2058. // paper.
  2059. #ifndef FP_IDCT
  2060. GBool DCTStream::readDataUnit(DCTHuffTable *dcHuffTable,
  2061.                   DCTHuffTable *acHuffTable,
  2062.                   Guchar quantTable[64], int *prevDC,
  2063.                   Guchar data[64]) {
  2064.   int tmp1[64];
  2065.   int v0, v1, v2, v3, v4, v5, v6, v7, t;
  2066.   int run, size, amp;
  2067.   int c;
  2068.   int i, j;
  2069.  
  2070.   // Huffman decode and dequantize
  2071.   size = readHuffSym(dcHuffTable);
  2072.   if (size == 9999)
  2073.     return gFalse;
  2074.   if (size > 0) {
  2075.     amp = readAmp(size);
  2076.     if (amp == 9999)
  2077.       return gFalse;
  2078.   } else {
  2079.     amp = 0;
  2080.   }
  2081.   tmp1[0] = (*prevDC += amp) * quantTable[0];
  2082.   for (i = 1; i < 64; ++i)
  2083.     tmp1[i] = 0;
  2084.   i = 1;
  2085.   while (i < 64) {
  2086.     run = 0;
  2087.     while ((c = readHuffSym(acHuffTable)) == 0xf0 && run < 0x30)
  2088.       run += 0x10;
  2089.     if (c == 9999)
  2090.       return gFalse;
  2091.     if (c == 0x00) {
  2092.       break;
  2093.     } else {
  2094.       run += (c >> 4) & 0x0f;
  2095.       size = c & 0x0f;
  2096.       amp = readAmp(size);
  2097.       if (amp == 9999)
  2098.     return gFalse;
  2099.       i += run;
  2100.       j = dctZigZag[i++];
  2101.       tmp1[j] = amp * quantTable[j];
  2102.     }
  2103.   }
  2104.  
  2105.   // inverse DCT on rows
  2106.   for (i = 0; i < 64; i += 8) {
  2107.  
  2108.     // stage 4
  2109.     v0 = (dctSqrt2 * tmp1[i+0] + 128) >> 8;
  2110.     v1 = (dctSqrt2 * tmp1[i+4] + 128) >> 8;
  2111.     v2 = tmp1[i+2];
  2112.     v3 = tmp1[i+6];
  2113.     v4 = (dctSqrt1d2 * (tmp1[i+1] - tmp1[i+7]) + 128) >> 8;
  2114.     v7 = (dctSqrt1d2 * (tmp1[i+1] + tmp1[i+7]) + 128) >> 8;
  2115.     v5 = tmp1[i+3] << 4;
  2116.     v6 = tmp1[i+5] << 4;
  2117.  
  2118.     // stage 3
  2119.     t = (v0 - v1+ 1) >> 1;
  2120.     v0 = (v0 + v1 + 1) >> 1;
  2121.     v1 = t;
  2122.     t = (v2 * dctSin6 + v3 * dctCos6 + 128) >> 8;
  2123.     v2 = (v2 * dctCos6 - v3 * dctSin6 + 128) >> 8;
  2124.     v3 = t;
  2125.     t = (v4 - v6 + 1) >> 1;
  2126.     v4 = (v4 + v6 + 1) >> 1;
  2127.     v6 = t;
  2128.     t = (v7 + v5 + 1) >> 1;
  2129.     v5 = (v7 - v5 + 1) >> 1;
  2130.     v7 = t;
  2131.  
  2132.     // stage 2
  2133.     t = (v0 - v3 + 1) >> 1;
  2134.     v0 = (v0 + v3 + 1) >> 1;
  2135.     v3 = t;
  2136.     t = (v1 - v2 + 1) >> 1;
  2137.     v1 = (v1 + v2 + 1) >> 1;
  2138.     v2 = t;
  2139.     t = (v4 * dctSin3 + v7 * dctCos3 + 2048) >> 12;
  2140.     v4 = (v4 * dctCos3 - v7 * dctSin3 + 2048) >> 12;
  2141.     v7 = t;
  2142.     t = (v5 * dctSin1 + v6 * dctCos1 + 2048) >> 12;
  2143.     v5 = (v5 * dctCos1 - v6 * dctSin1 + 2048) >> 12;
  2144.     v6 = t;
  2145.  
  2146.     // stage 1
  2147.     tmp1[i+0] = v0 + v7;
  2148.     tmp1[i+7] = v0 - v7;
  2149.     tmp1[i+1] = v1 + v6;
  2150.     tmp1[i+6] = v1 - v6;
  2151.     tmp1[i+2] = v2 + v5;
  2152.     tmp1[i+5] = v2 - v5;
  2153.     tmp1[i+3] = v3 + v4;
  2154.     tmp1[i+4] = v3 - v4;
  2155.   }
  2156.  
  2157.   // inverse DCT on columns
  2158.   for (i = 0; i < 8; ++i) {
  2159.  
  2160.     // stage 4
  2161.     v0 = (dctSqrt2 * tmp1[0*8+i] + 2048) >> 12;
  2162.     v1 = (dctSqrt2 * tmp1[4*8+i] + 2048) >> 12;
  2163.     v2 = tmp1[2*8+i];
  2164.     v3 = tmp1[6*8+i];
  2165.     v4 = (dctSqrt1d2 * (tmp1[1*8+i] - tmp1[7*8+i]) + 2048) >> 12;
  2166.     v7 = (dctSqrt1d2 * (tmp1[1*8+i] + tmp1[7*8+i]) + 2048) >> 12;
  2167.     v5 = tmp1[3*8+i];
  2168.     v6 = tmp1[5*8+i];
  2169.  
  2170.     // stage 3
  2171.     t = (v0 - v1 + 1) >> 1;
  2172.     v0 = (v0 + v1 + 1) >> 1;
  2173.     v1 = t;
  2174.     t = (v2 * dctSin6 + v3 * dctCos6 + 2048) >> 12;
  2175.     v2 = (v2 * dctCos6 - v3 * dctSin6 + 2048) >> 12;
  2176.     v3 = t;
  2177.     t = (v4 - v6 + 1) >> 1;
  2178.     v4 = (v4 + v6 + 1) >> 1;
  2179.     v6 = t;
  2180.     t = (v7 + v5 + 1) >> 1;
  2181.     v5 = (v7 - v5 + 1) >> 1;
  2182.     v7 = t;
  2183.  
  2184.     // stage 2
  2185.     t = (v0 - v3 + 1) >> 1;
  2186.     v0 = (v0 + v3 + 1) >> 1;
  2187.     v3 = t;
  2188.     t = (v1 - v2 + 1) >> 1;
  2189.     v1 = (v1 + v2 + 1) >> 1;
  2190.     v2 = t;
  2191.     t = (v4 * dctSin3 + v7 * dctCos3 + 2048) >> 12;
  2192.     v4 = (v4 * dctCos3 - v7 * dctSin3 + 2048) >> 12;
  2193.     v7 = t;
  2194.     t = (v5 * dctSin1 + v6 * dctCos1 + 2048) >> 12;
  2195.     v5 = (v5 * dctCos1 - v6 * dctSin1 + 2048) >> 12;
  2196.     v6 = t;
  2197.  
  2198.     // stage 1
  2199.     tmp1[0*8+i] = v0 + v7;
  2200.     tmp1[7*8+i] = v0 - v7;
  2201.     tmp1[1*8+i] = v1 + v6;
  2202.     tmp1[6*8+i] = v1 - v6;
  2203.     tmp1[2*8+i] = v2 + v5;
  2204.     tmp1[5*8+i] = v2 - v5;
  2205.     tmp1[3*8+i] = v3 + v4;
  2206.     tmp1[4*8+i] = v3 - v4;
  2207.   }
  2208.  
  2209.   // convert to 8-bit integers
  2210.   for (i = 0; i < 64; ++i)
  2211.     data[i] = dctClip[dctClipOffset + 128 + ((tmp1[i] + 8) >> 4)];
  2212.  
  2213.   return gTrue;
  2214. }
  2215. #endif
  2216.  
  2217. #ifdef FP_IDCT
  2218. GBool DCTStream::readDataUnit(DCTHuffTable *dcHuffTable,
  2219.                   DCTHuffTable *acHuffTable,
  2220.                   Guchar quantTable[64], int *prevDC,
  2221.                   Guchar data[64]) {
  2222.   double tmp1[64];
  2223.   double v0, v1, v2, v3, v4, v5, v6, v7, t;
  2224.   int run, size, amp;
  2225.   int c;
  2226.   int i, j;
  2227.  
  2228.   // Huffman decode and dequantize
  2229.   size = readHuffSym(dcHuffTable);
  2230.   if (size == 9999)
  2231.     return gFalse;
  2232.   if (size > 0) {
  2233.     amp = readAmp(size);
  2234.     if (amp == 9999)
  2235.       return gFalse;
  2236.   } else {
  2237.     amp = 0;
  2238.   }
  2239.   tmp1[0] = (*prevDC += amp) * quantTable[0];
  2240.   for (i = 1; i < 64; ++i)
  2241.     tmp1[i] = 0;
  2242.   i = 1;
  2243.   while (i < 64) {
  2244.     run = 0;
  2245.     while ((c = readHuffSym(acHuffTable)) == 0xf0 && run < 0x30)
  2246.       run += 0x10;
  2247.     if (c == 9999)
  2248.       return gFalse;
  2249.     if (c == 0x00) {
  2250.       break;
  2251.     } else {
  2252.       run += (c >> 4) & 0x0f;
  2253.       size = c & 0x0f;
  2254.       amp = readAmp(size);
  2255.       if (amp == 9999)
  2256.     return gFalse;
  2257.       i += run;
  2258.       j = dctZigZag[i++];
  2259.       tmp1[j] = amp * quantTable[j];
  2260.     }
  2261.   }
  2262.  
  2263.   // inverse DCT on rows
  2264.   for (i = 0; i < 64; i += 8) {
  2265.  
  2266.     // stage 4
  2267.     v0 = dctSqrt2 * tmp1[i+0];
  2268.     v1 = dctSqrt2 * tmp1[i+4];
  2269.     v2 = tmp1[i+2];
  2270.     v3 = tmp1[i+6];
  2271.     v4 = dctSqrt1d2 * (tmp1[i+1] - tmp1[i+7]);
  2272.     v7 = dctSqrt1d2 * (tmp1[i+1] + tmp1[i+7]);
  2273.     v5 = tmp1[i+3];
  2274.     v6 = tmp1[i+5];
  2275.  
  2276.     // stage 3
  2277.     t = 0.5 * (v0 - v1);
  2278.     v0 = 0.5 * (v0 + v1);
  2279.     v1 = t;
  2280.     t = v2 * dctSin6 + v3 * dctCos6;
  2281.     v2 = v2 * dctCos6 - v3 * dctSin6;
  2282.     v3 = t;
  2283.     t = 0.5 * (v4 - v6);
  2284.     v4 = 0.5 * (v4 + v6);
  2285.     v6 = t;
  2286.     t = 0.5 * (v7 + v5);
  2287.     v5 = 0.5 * (v7 - v5);
  2288.     v7 = t;
  2289.  
  2290.     // stage 2
  2291.     t = 0.5 * (v0 - v3);
  2292.     v0 = 0.5 * (v0 + v3);
  2293.     v3 = t;
  2294.     t = 0.5 * (v1 - v2);
  2295.     v1 = 0.5 * (v1 + v2);
  2296.     v2 = t;
  2297.     t = v4 * dctSin3 + v7 * dctCos3;
  2298.     v4 = v4 * dctCos3 - v7 * dctSin3;
  2299.     v7 = t;
  2300.     t = v5 * dctSin1 + v6 * dctCos1;
  2301.     v5 = v5 * dctCos1 - v6 * dctSin1;
  2302.     v6 = t;
  2303.  
  2304.     // stage 1
  2305.     tmp1[i+0] = v0 + v7;
  2306.     tmp1[i+7] = v0 - v7;
  2307.     tmp1[i+1] = v1 + v6;
  2308.     tmp1[i+6] = v1 - v6;
  2309.     tmp1[i+2] = v2 + v5;
  2310.     tmp1[i+5] = v2 - v5;
  2311.     tmp1[i+3] = v3 + v4;
  2312.     tmp1[i+4] = v3 - v4;
  2313.   }
  2314.  
  2315.   // inverse DCT on columns
  2316.   for (i = 0; i < 8; ++i) {
  2317.  
  2318.     // stage 4
  2319.     v0 = dctSqrt2 * tmp1[0*8+i];
  2320.     v1 = dctSqrt2 * tmp1[4*8+i];
  2321.     v2 = tmp1[2*8+i];
  2322.     v3 = tmp1[6*8+i];
  2323.     v4 = dctSqrt1d2 * (tmp1[1*8+i] - tmp1[7*8+i]);
  2324.     v7 = dctSqrt1d2 * (tmp1[1*8+i] + tmp1[7*8+i]);
  2325.     v5 = tmp1[3*8+i];
  2326.     v6 = tmp1[5*8+i];
  2327.  
  2328.     // stage 3
  2329.     t = 0.5 * (v0 - v1);
  2330.     v0 = 0.5 * (v0 + v1);
  2331.     v1 = t;
  2332.     t = v2 * dctSin6 + v3 * dctCos6;
  2333.     v2 = v2 * dctCos6 - v3 * dctSin6;
  2334.     v3 = t;
  2335.     t = 0.5 * (v4 - v6);
  2336.     v4 = 0.5 * (v4 + v6);
  2337.     v6 = t;
  2338.     t = 0.5 * (v7 + v5);
  2339.     v5 = 0.5 * (v7 - v5);
  2340.     v7 = t;
  2341.  
  2342.     // stage 2
  2343.     t = 0.5 * (v0 - v3);
  2344.     v0 = 0.5 * (v0 + v3);
  2345.     v3 = t;
  2346.     t = 0.5 * (v1 - v2);
  2347.     v1 = 0.5 * (v1 + v2);
  2348.     v2 = t;
  2349.     t = v4 * dctSin3 + v7 * dctCos3;
  2350.     v4 = v4 * dctCos3 - v7 * dctSin3;
  2351.     v7 = t;
  2352.     t = v5 * dctSin1 + v6 * dctCos1;
  2353.     v5 = v5 * dctCos1 - v6 * dctSin1;
  2354.     v6 = t;
  2355.  
  2356.     // stage 1
  2357.     tmp1[0*8+i] = v0 + v7;
  2358.     tmp1[7*8+i] = v0 - v7;
  2359.     tmp1[1*8+i] = v1 + v6;
  2360.     tmp1[6*8+i] = v1 - v6;
  2361.     tmp1[2*8+i] = v2 + v5;
  2362.     tmp1[5*8+i] = v2 - v5;
  2363.     tmp1[3*8+i] = v3 + v4;
  2364.     tmp1[4*8+i] = v3 - v4;
  2365.   }
  2366.  
  2367.   // convert to 8-bit integers
  2368.   for (i = 0; i < 64; ++i)
  2369.     data[i] = dctClip[dctClipOffset + (int)(tmp1[i] + 128.5)];
  2370.  
  2371.   return gTrue;
  2372. }
  2373. #endif
  2374.  
  2375. int DCTStream::readHuffSym(DCTHuffTable *table) {
  2376.   Gushort code;
  2377.   int bit;
  2378.   int codeBits;
  2379.  
  2380.   code = 0;
  2381.   codeBits = 0;
  2382.   do {
  2383.     // add a bit to the code
  2384.     if ((bit = readBit()) == EOF)
  2385.       return 9999;
  2386.     code = (code << 1) + bit;
  2387.     ++codeBits;
  2388.  
  2389.     // look up code
  2390.     if (code - table->firstCode[codeBits] < table->numCodes[codeBits]) {
  2391.       code -= table->firstCode[codeBits];
  2392.       return table->sym[table->firstSym[codeBits] + code];
  2393.     }
  2394.   } while (codeBits < 16);
  2395.  
  2396.   error(getPos(), R_BAD_HUFFMAN_CODE_IN_DCT_STREAM);
  2397.   return 9999;
  2398. }
  2399.  
  2400. int DCTStream::readAmp(int size) {
  2401.   int amp, bit;
  2402.   int bits;
  2403.  
  2404.   amp = 0;
  2405.   for (bits = 0; bits < size; ++bits) {
  2406.     if ((bit = readBit()) == EOF)
  2407.       return 9999;
  2408.     amp = (amp << 1) + bit;
  2409.   }
  2410.   if (amp < (1 << (size - 1)))
  2411.     amp -= (1 << size) - 1;
  2412.   return amp;
  2413. }
  2414.  
  2415. int DCTStream::readBit() {
  2416.   int bit;
  2417.   int c, c2;
  2418.  
  2419.   if (inputBits == 0) {
  2420.     if ((c = str->getChar()) == EOF)
  2421.       return EOF;
  2422.     if (c == 0xff) {
  2423.       do {
  2424.     c2 = str->getChar();
  2425.       } while (c2 == 0xff);
  2426.       if (c2 != 0x00) {
  2427.     error(getPos(), R_BAD_DCT_DATA__MISSING_00_AFTER_FF);
  2428.     return EOF;
  2429.       }
  2430.     }
  2431.     inputBuf = c;
  2432.     inputBits = 8;
  2433.   }
  2434.   bit = (inputBuf >> (inputBits - 1)) & 1;
  2435.   --inputBits;
  2436.   return bit;
  2437. }
  2438.  
  2439. GBool DCTStream::readHeaderL() {
  2440.   GBool doScan;
  2441.   int minHSample, minVSample;
  2442.   int bufWidth;
  2443.   int n;
  2444.   int c = 0;
  2445.   int i, j;
  2446.  
  2447.   width = height = 0;
  2448.   numComps = 0;
  2449.   numQuantTables = 0;
  2450.   numDCHuffTables = 0;
  2451.   numACHuffTables = 0;
  2452.   colorXform = 0;
  2453.   gotAdobeMarker = gFalse;
  2454.   restartInterval = 0;
  2455.  
  2456.   // read headers
  2457.   doScan = gFalse;
  2458.   while (!doScan) {
  2459.     c = readMarker();
  2460.     switch (c) {
  2461.     case 0xc0:            // SOF0
  2462.       if (!readFrameInfo())
  2463.     return gFalse;
  2464.       break;
  2465.     case 0xc4:            // DHT
  2466.       if (!readHuffmanTables())
  2467.     return gFalse;
  2468.       break;
  2469.     case 0xd8:            // SOI
  2470.       break;
  2471.     case 0xda:            // SOS
  2472.       if (!readScanInfo())
  2473.     return gFalse;
  2474.       doScan = gTrue;
  2475.       break;
  2476.     case 0xdb:            // DQT
  2477.       if (!readQuantTables())
  2478.     return gFalse;
  2479.       break;
  2480.     case 0xdd:            // DRI
  2481.       if (!readRestartInterval())
  2482.     return gFalse;
  2483.       break;
  2484.     case 0xee:            // APP14
  2485.       if (!readAdobeMarker())
  2486.     return gFalse;
  2487.       break;
  2488.     case EOF:
  2489.       error(getPos(), R_BAD_DCT_HEADER);
  2490.       return gFalse;
  2491.     default:
  2492.       // skip APPn / COM / etc.
  2493.       if (c >= 0xe0) {
  2494.     n = read16() - 2;
  2495.     for (i = 0; i < n; ++i)
  2496.       str->getChar();
  2497.       } else {
  2498.     error(getPos(), R_UNKNOWN_DCT_MARKER___02X_, c);
  2499.     return gFalse;
  2500.       }
  2501.       break;
  2502.     }
  2503.   }
  2504.  
  2505.   // compute MCU size
  2506.   mcuWidth = minHSample = compInfo[0].hSample;
  2507.   mcuHeight = minVSample = compInfo[0].vSample;
  2508.   for (i = 1; i < numComps; ++i) {
  2509.     if (compInfo[i].hSample < minHSample)
  2510.       minHSample = compInfo[i].hSample;
  2511.     if (compInfo[i].vSample < minVSample)
  2512.       minVSample = compInfo[i].vSample;
  2513.     if (compInfo[i].hSample > mcuWidth)
  2514.       mcuWidth = compInfo[i].hSample;
  2515.     if (compInfo[i].vSample > mcuHeight)
  2516.       mcuHeight = compInfo[i].vSample;
  2517.   }
  2518.   for (i = 0; i < numComps; ++i) {
  2519.     compInfo[i].hSample /= minHSample;
  2520.     compInfo[i].vSample /= minVSample;
  2521.   }
  2522.   mcuWidth = (mcuWidth / minHSample) * 8;
  2523.   mcuHeight = (mcuHeight / minVSample) * 8;
  2524.  
  2525.   // allocate buffers, but clear first for proper cleanup
  2526.   bufWidth = ((width + mcuWidth - 1) / mcuWidth) * mcuWidth;
  2527.   for (i = 0; i < numComps; ++i)
  2528.     for (j = 0; j < mcuHeight; ++j)
  2529.       rowBuf[i][j] = 0;
  2530.   for (i = 0; i < numComps; ++i)
  2531.     for (j = 0; j < mcuHeight; ++j)
  2532.       rowBuf[i][j] = (Guchar *)User::AllocL(bufWidth * sizeof(Guchar));
  2533.  
  2534.   // figure out color transform
  2535.   if (!gotAdobeMarker && numComps == 3) {
  2536.     if (compInfo[0].id == 1 && compInfo[1].id == 2 && compInfo[2].id == 3) {
  2537.       colorXform = 1;
  2538.     }
  2539.   }
  2540.  
  2541.   // initialize counters
  2542.   comp = 0;
  2543.   x = 0;
  2544.   y = 0;
  2545.   dy = mcuHeight;
  2546.  
  2547.   return gTrue;
  2548. }
  2549.  
  2550. GBool DCTStream::readFrameInfo() {
  2551.   int length;
  2552.   int prec;
  2553.   int i;
  2554.   int c;
  2555.  
  2556.   length = read16() - 2;
  2557.   prec = str->getChar();
  2558.   height = read16();
  2559.   width = read16();
  2560.   numComps = str->getChar();
  2561.   length -= 6;
  2562.   if (prec != 8) {
  2563.     error(getPos(), R_BAD_DCT_PRECISION__D, prec);
  2564.     return gFalse;
  2565.   }
  2566.   for (i = 0; i < numComps; ++i) {
  2567.     compInfo[i].id = str->getChar();
  2568.     compInfo[i].inScan = gFalse;
  2569.     c = str->getChar();
  2570.     compInfo[i].hSample = (c >> 4) & 0x0f;
  2571.     compInfo[i].vSample = c & 0x0f;
  2572.     compInfo[i].quantTable = str->getChar();
  2573.     compInfo[i].dcHuffTable = 0;
  2574.     compInfo[i].acHuffTable = 0;
  2575.   }
  2576.   return gTrue;
  2577. }
  2578.  
  2579. GBool DCTStream::readScanInfo() {
  2580.   int length;
  2581.   int scanComps, id, c;
  2582.   int i, j;
  2583.  
  2584.   length = read16() - 2;
  2585.   scanComps = str->getChar();
  2586.   --length;
  2587.   if (length != 2 * scanComps + 3) {
  2588.     error(getPos(), R_BAD_DCT_SCAN_INFO_BLOCK);
  2589.     return gFalse;
  2590.   }
  2591.   for (i = 0; i < scanComps; ++i) {
  2592.     id = str->getChar();
  2593.     for (j = 0; j < numComps; ++j) {
  2594.       if (id == compInfo[j].id)
  2595.     break;
  2596.     }
  2597.     if (j == numComps) {
  2598.       error(getPos(), R_BAD_DCT_COMPONENT_ID_IN_SCAN_INFO_BLOCK);
  2599.       return gFalse;
  2600.     }
  2601.     compInfo[j].inScan = gTrue;
  2602.     c = str->getChar();
  2603.     compInfo[j].dcHuffTable = (c >> 4) & 0x0f;
  2604.     compInfo[j].acHuffTable = c & 0x0f;
  2605.   }
  2606.   str->getChar();
  2607.   str->getChar();
  2608.   str->getChar();
  2609.   return gTrue;
  2610. }
  2611.  
  2612. GBool DCTStream::readQuantTables() {
  2613.   int length;
  2614.   int i;
  2615.   int index;
  2616.  
  2617.   length = read16() - 2;
  2618.   while (length > 0) {
  2619.     index = str->getChar();
  2620.     if ((index & 0xf0) || index >= 4) {
  2621.       error(getPos(), R_BAD_DCT_QUANTIZATION_TABLE);
  2622.       return gFalse;
  2623.     }
  2624.     if (index == numQuantTables)
  2625.       numQuantTables = index + 1;
  2626.     for (i = 0; i < 64; ++i)
  2627.       quantTables[index][dctZigZag[i]] = str->getChar();
  2628.     length -= 65;
  2629.   }
  2630.   return gTrue;
  2631. }
  2632.  
  2633. GBool DCTStream::readHuffmanTables() {
  2634.   DCTHuffTable *tbl;
  2635.   int length;
  2636.   int index;
  2637.   Gushort code;
  2638.   Guchar sym;
  2639.   int i;
  2640.   int c;
  2641.  
  2642.   length = read16() - 2;
  2643.   while (length > 0) {
  2644.     index = str->getChar();
  2645.     --length;
  2646.     if ((index & 0x0f) >= 4) {
  2647.       error(getPos(), R_BAD_DCT_HUFFMAN_TABLE);
  2648.       return gFalse;
  2649.     }
  2650.     if (index & 0x10) {
  2651.       index &= 0x0f;
  2652.       if (index >= numACHuffTables)
  2653.     numACHuffTables = index+1;
  2654.       tbl = &acHuffTables[index];
  2655.     } else {
  2656.       if (index >= numDCHuffTables)
  2657.     numDCHuffTables = index+1;
  2658.       tbl = &dcHuffTables[index];
  2659.     }
  2660.     sym = 0;
  2661.     code = 0;
  2662.     for (i = 1; i <= 16; ++i) {
  2663.       c = str->getChar();
  2664.       tbl->firstSym[i] = sym;
  2665.       tbl->firstCode[i] = code;
  2666.       tbl->numCodes[i] = c;
  2667.       sym += c;
  2668.       code = (code + c) << 1;
  2669.     }
  2670.     length -= 16;
  2671.     for (i = 0; i < sym; ++i)
  2672.       tbl->sym[i] = str->getChar();
  2673.     length -= sym;
  2674.   }
  2675.   return gTrue;
  2676. }
  2677.  
  2678. GBool DCTStream::readRestartInterval() {
  2679.   int length;
  2680.  
  2681.   length = read16();
  2682.   if (length != 4) {
  2683.     error(getPos(), R_BAD_DCT_RESTART_INTERVAL);
  2684.     return gFalse;
  2685.   }
  2686.   restartInterval = read16();
  2687.   return gTrue;
  2688. }
  2689.  
  2690. GBool DCTStream::readAdobeMarker() {
  2691.   int length, i;
  2692.   char buf[12];
  2693.   int c;
  2694.  
  2695.   length = read16();
  2696.   if (length != 14)
  2697.     goto err;
  2698.   for (i = 0; i < 12; ++i) {
  2699.     if ((c = str->getChar()) == EOF)
  2700.       goto err;
  2701.     buf[i] = c;
  2702.   }
  2703.   if (strncmp(buf, "Adobe", 5))
  2704.     goto err;
  2705.   colorXform = buf[11];
  2706.   gotAdobeMarker = gTrue;
  2707.   return gTrue;
  2708.  
  2709.  err:
  2710.   error(getPos(), R_BAD_DCT_ADOBE_APP14_MARKER);
  2711.   return gFalse;
  2712. }
  2713.  
  2714. GBool DCTStream::readTrailer() {
  2715.   int c;
  2716.  
  2717.   c = readMarker();
  2718.   if (c != 0xd9) {        // EOI
  2719.     error(getPos(), R_BAD_DCT_TRAILER);
  2720.     return gFalse;
  2721.   }
  2722.   return gTrue;
  2723. }
  2724.  
  2725. int DCTStream::readMarker() {
  2726.   int c;
  2727.  
  2728.   do {
  2729.     do {
  2730.       c = str->getChar();
  2731.     } while (c != 0xff);
  2732.     do {
  2733.       c = str->getChar();
  2734.     } while (c == 0xff);
  2735.   } while (c == 0x00);
  2736.   return c;
  2737. }
  2738.  
  2739. int DCTStream::read16() {
  2740.   int c1, c2;
  2741.  
  2742.   if ((c1 = str->getChar()) == EOF)
  2743.     return EOF;
  2744.   if ((c2 = str->getChar()) == EOF)
  2745.     return EOF;
  2746.   return (c1 << 8) + c2;
  2747. }
  2748.  
  2749. GString *DCTStream::getPSFilterL(char *indent) {
  2750.   GString *s;
  2751.  
  2752.   s = str->getPSFilterL(indent);
  2753.   s->appendL(indent)->appendL("<< >> /DCTDecode filter\n");
  2754.   return s;
  2755. }
  2756.  
  2757. GBool DCTStream::isBinary(GBool /* last */) {
  2758.   return str->isBinary(gTrue);
  2759. }
  2760.  
  2761. //------------------------------------------------------------------------
  2762. // FlateStream
  2763. //------------------------------------------------------------------------
  2764.  
  2765. const int FlateStream::codeLenCodeMap[flateMaxCodeLenCodes] = {
  2766.   16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15
  2767. };
  2768.  
  2769. const FlateDecode FlateStream::lengthDecode[flateMaxLitCodes-257] = {
  2770.   {0,   3},
  2771.   {0,   4},
  2772.   {0,   5},
  2773.   {0,   6},
  2774.   {0,   7},
  2775.   {0,   8},
  2776.   {0,   9},
  2777.   {0,  10},
  2778.   {1,  11},
  2779.   {1,  13},
  2780.   {1,  15},
  2781.   {1,  17},
  2782.   {2,  19},
  2783.   {2,  23},
  2784.   {2,  27},
  2785.   {2,  31},
  2786.   {3,  35},
  2787.   {3,  43},
  2788.   {3,  51},
  2789.   {3,  59},
  2790.   {4,  67},
  2791.   {4,  83},
  2792.   {4,  99},
  2793.   {4, 115},
  2794.   {5, 131},
  2795.   {5, 163},
  2796.   {5, 195},
  2797.   {5, 227},
  2798.   {0, 258}
  2799. };
  2800.  
  2801. const FlateDecode FlateStream::distDecode[flateMaxDistCodes] = {
  2802.   { 0,     1},
  2803.   { 0,     2},
  2804.   { 0,     3},
  2805.   { 0,     4},
  2806.   { 1,     5},
  2807.   { 1,     7},
  2808.   { 2,     9},
  2809.   { 2,    13},
  2810.   { 3,    17},
  2811.   { 3,    25},
  2812.   { 4,    33},
  2813.   { 4,    49},
  2814.   { 5,    65},
  2815.   { 5,    97},
  2816.   { 6,   129},
  2817.   { 6,   193},
  2818.   { 7,   257},
  2819.   { 7,   385},
  2820.   { 8,   513},
  2821.   { 8,   769},
  2822.   { 9,  1025},
  2823.   { 9,  1537},
  2824.   {10,  2049},
  2825.   {10,  3073},
  2826.   {11,  4097},
  2827.   {11,  6145},
  2828.   {12,  8193},
  2829.   {12, 12289},
  2830.   {13, 16385},
  2831.   {13, 24577}
  2832. };
  2833.  
  2834. FlateStream::FlateStream(Stream *str1): str(str1) {}
  2835.  
  2836. void FlateStream::ConstructL(int predictor1, int columns1, int colors1, int bits1)
  2837. {
  2838.   if (predictor1 != 1) {
  2839.     pred = new(ELeave) StreamPredictor(this, predictor1, columns1, colors1, bits1);
  2840.     pred->ConstructL();
  2841.   } else {
  2842.     pred = 0;
  2843.   }
  2844. }
  2845.  
  2846. FlateStream::~FlateStream() {
  2847.   delete pred;
  2848.   delete str;
  2849. }
  2850.  
  2851. void FlateStream::reset() {
  2852.   int cmf, flg;
  2853.  
  2854.   str->reset();
  2855.  
  2856.   // read header
  2857.   //~ need to look at window size?
  2858.   endOfBlock = eof = gTrue;
  2859.   cmf = str->getChar();
  2860.   flg = str->getChar();
  2861.   if (cmf == EOF || flg == EOF)
  2862.     return;
  2863.   if ((cmf & 0x0f) != 0x08) {
  2864.     error(getPos(), R_UNKNOWN_COMPRESSION_METHOD_IN_FLATE_STREAM);
  2865.     return;
  2866.   }
  2867.   if ((((cmf << 8) + flg) % 31) != 0) {
  2868.     error(getPos(), R_BAD_FCHECK_IN_FLATE_STREAM);
  2869.     return;
  2870.   }
  2871.   if (flg & 0x20) {
  2872.     error(getPos(), R_FDICT_BIT_SET_IN_FLATE_STREAM);
  2873.     return;
  2874.   }
  2875.  
  2876.   // initialize
  2877.   index = 0;
  2878.   remain = 0;
  2879.   codeBuf = 0;
  2880.   codeSize = 0;
  2881.   compressedBlock = gFalse;
  2882.   endOfBlock = gTrue;
  2883.   eof = gFalse;
  2884. }
  2885.  
  2886. int FlateStream::getChar() {
  2887.   int c;
  2888.  
  2889.   if (pred) {
  2890.     return pred->getChar();
  2891.   }
  2892.   while (remain == 0) {
  2893.     if (endOfBlock && eof)
  2894.       return EOF;
  2895.     readSome();
  2896.   }
  2897.   c = buf[index];
  2898.   index = (index + 1) & flateMask;
  2899.   --remain;
  2900.   return c;
  2901. }
  2902.  
  2903. int FlateStream::lookChar() {
  2904.   int c;
  2905.  
  2906.   if (pred) {
  2907.     return pred->lookChar();
  2908.   }
  2909.   while (remain == 0) {
  2910.     if (endOfBlock && eof)
  2911.       return EOF;
  2912.     readSome();
  2913.   }
  2914.   c = buf[index];
  2915.   return c;
  2916. }
  2917.  
  2918. int FlateStream::getRawChar() {
  2919.   int c;
  2920.  
  2921.   while (remain == 0) {
  2922.     if (endOfBlock && eof)
  2923.       return EOF;
  2924.     readSome();
  2925.   }
  2926.   c = buf[index];
  2927.   index = (index + 1) & flateMask;
  2928.   --remain;
  2929.   return c;
  2930. }
  2931.  
  2932. GString *FlateStream::getPSFilterL(char * /* indent */) {
  2933.   return NULL;
  2934. }
  2935.  
  2936. GBool FlateStream::isBinary(GBool /* last */) {
  2937.   return str->isBinary(gTrue);
  2938. }
  2939.  
  2940. void FlateStream::readSome() {
  2941.   int code1, code2;
  2942.   int len, dist;
  2943.   int i, j, k;
  2944.   int c;
  2945.  
  2946.   if (endOfBlock) {
  2947.     if (!startBlock())
  2948.       return;
  2949.   }
  2950.  
  2951.   if (compressedBlock) {
  2952.     if ((code1 = getHuffmanCodeWord(&litCodeTab)) == EOF)
  2953.       goto err;
  2954.     if (code1 < 256) {
  2955.       buf[index] = code1;
  2956.       remain = 1;
  2957.     } else if (code1 == 256) {
  2958.       endOfBlock = gTrue;
  2959.       remain = 0;
  2960.     } else {
  2961.       code1 -= 257;
  2962.       code2 = lengthDecode[code1].bits;
  2963.       if (code2 > 0 && (code2 = getCodeWord(code2)) == EOF)
  2964.     goto err;
  2965.       len = lengthDecode[code1].first + code2;
  2966.       if ((code1 = getHuffmanCodeWord(&distCodeTab)) == EOF)
  2967.     goto err;
  2968.       code2 = distDecode[code1].bits;
  2969.       if (code2 > 0 && (code2 = getCodeWord(code2)) == EOF)
  2970.     goto err;
  2971.       dist = distDecode[code1].first + code2;
  2972.       i = index;
  2973.       j = (index - dist) & flateMask;
  2974.       for (k = 0; k < len; ++k) {
  2975.     buf[i] = buf[j];
  2976.     i = (i + 1) & flateMask;
  2977.     j = (j + 1) & flateMask;
  2978.       }
  2979.       remain = len;
  2980.     }
  2981.  
  2982.   } else {
  2983.     len = (blockLen < flateWindow) ? blockLen : flateWindow;
  2984.     for (i = 0, j = index; i < len; ++i, j = (j + 1) & flateMask) {
  2985.       if ((c = str->getChar()) == EOF) {
  2986.     endOfBlock = eof = gTrue;
  2987.     break;
  2988.       }
  2989.       buf[j] = c & 0xff;
  2990.     }
  2991.     remain = i;
  2992.     blockLen -= len;
  2993.     if (blockLen == 0)
  2994.       endOfBlock = gTrue;
  2995.   }
  2996.  
  2997.   return;
  2998.  
  2999. err:
  3000.   error(getPos(), R_UNEXPECTED_END_OF_FILE_IN_FLATE_STREAM);
  3001.   endOfBlock = eof = gTrue;
  3002.   remain = 0;
  3003. }
  3004.  
  3005. GBool FlateStream::startBlock() {
  3006.   int blockHdr;
  3007.   int c;
  3008.   int check;
  3009.  
  3010.   // read block header
  3011.   blockHdr = getCodeWord(3);
  3012.   if (blockHdr & 1)
  3013.     eof = gTrue;
  3014.   blockHdr >>= 1;
  3015.  
  3016.   // uncompressed block
  3017.   if (blockHdr == 0) {
  3018.     compressedBlock = gFalse;
  3019.     if ((c = str->getChar()) == EOF)
  3020.       goto err;
  3021.     blockLen = c & 0xff;
  3022.     if ((c = str->getChar()) == EOF)
  3023.       goto err;
  3024.     blockLen |= (c & 0xff) << 8;
  3025.     if ((c = str->getChar()) == EOF)
  3026.       goto err;
  3027.     check = c & 0xff;
  3028.     if ((c = str->getChar()) == EOF)
  3029.       goto err;
  3030.     check |= (c & 0xff) << 8;
  3031.     if (check != (~blockLen & 0xffff))
  3032.       error(getPos(), R_BAD_UNCOMPRESSED_BLOCK_LENGTH_IN_FLATE_STREAM);
  3033.     codeBuf = 0;
  3034.     codeSize = 0;
  3035.  
  3036.   // compressed block with fixed codes
  3037.   } else if (blockHdr == 1) {
  3038.     compressedBlock = gTrue;
  3039.     loadFixedCodes();
  3040.  
  3041.   // compressed block with dynamic codes
  3042.   } else if (blockHdr == 2) {
  3043.     compressedBlock = gTrue;
  3044.     if (!readDynamicCodes())
  3045.       goto err;
  3046.  
  3047.   // unknown block type
  3048.   } else {
  3049.     goto err;
  3050.   }
  3051.  
  3052.   endOfBlock = gFalse;
  3053.   return gTrue;
  3054.  
  3055. err:
  3056.   error(getPos(), R_BAD_BLOCK_HEADER_IN_FLATE_STREAM);
  3057.   endOfBlock = eof = gTrue;
  3058.   return gFalse;
  3059. }
  3060.  
  3061. void FlateStream::loadFixedCodes() {
  3062.   int i;
  3063.  
  3064.   // set up code arrays
  3065.   litCodeTab.codes = allCodes;
  3066.   distCodeTab.codes = allCodes + flateMaxLitCodes;
  3067.  
  3068.   // initialize literal code table
  3069.   for (i = 0; i <= 143; ++i)
  3070.     litCodeTab.codes[i].len = 8;
  3071.   for (i = 144; i <= 255; ++i)
  3072.     litCodeTab.codes[i].len = 9;
  3073.   for (i = 256; i <= 279; ++i)
  3074.     litCodeTab.codes[i].len = 7;
  3075.   for (i = 280; i <= 287; ++i)
  3076.     litCodeTab.codes[i].len = 8;
  3077.   compHuffmanCodes(&litCodeTab, flateMaxLitCodes);
  3078.  
  3079.   // initialize distance code table
  3080.   for (i = 0; i <= 5; ++i) {
  3081.     distCodeTab.start[i] = 0;
  3082.   }
  3083.   for (i = 6; i <= flateMaxHuffman+1; ++i){
  3084.     distCodeTab.start[i] = flateMaxDistCodes;
  3085.   }
  3086.   for (i = 0; i < flateMaxDistCodes; ++i) {
  3087.     distCodeTab.codes[i].len = 5;
  3088.     distCodeTab.codes[i].code = i;
  3089.     distCodeTab.codes[i].val = i;
  3090.   }
  3091. }
  3092.  
  3093. GBool FlateStream::readDynamicCodes() {
  3094.   int numCodeLenCodes;
  3095.   int numLitCodes;
  3096.   int numDistCodes;
  3097.   FlateCode codeLenCodes[flateMaxCodeLenCodes];
  3098.   FlateHuffmanTab codeLenCodeTab;
  3099.   int len, repeat, code;
  3100.   int i;
  3101.  
  3102.   // read lengths
  3103.   if ((numLitCodes = getCodeWord(5)) == EOF)
  3104.     goto err;
  3105.   numLitCodes += 257;
  3106.   if ((numDistCodes = getCodeWord(5)) == EOF)
  3107.     goto err;
  3108.   numDistCodes += 1;
  3109.   if ((numCodeLenCodes = getCodeWord(4)) == EOF)
  3110.     goto err;
  3111.   numCodeLenCodes += 4;
  3112.   if (numLitCodes > flateMaxLitCodes ||
  3113.       numDistCodes > flateMaxDistCodes ||
  3114.       numCodeLenCodes > flateMaxCodeLenCodes)
  3115.     goto err;
  3116.  
  3117.   // read code length code table
  3118.   codeLenCodeTab.codes = codeLenCodes;
  3119.   for (i = 0; i < flateMaxCodeLenCodes; ++i)
  3120.     codeLenCodes[i].len = 0;
  3121.   for (i = 0; i < numCodeLenCodes; ++i) {
  3122.     if ((codeLenCodes[codeLenCodeMap[i]].len = getCodeWord(3)) == -1)
  3123.       goto err;
  3124.   }
  3125.   compHuffmanCodes(&codeLenCodeTab, flateMaxCodeLenCodes);
  3126.  
  3127.   // set up code arrays
  3128.   litCodeTab.codes = allCodes;
  3129.   distCodeTab.codes = allCodes + numLitCodes;
  3130.  
  3131.   // read literal and distance code tables
  3132.   len = 0;
  3133.   repeat = 0;
  3134.   i = 0;
  3135.   while (i < numLitCodes + numDistCodes) {
  3136.     if ((code = getHuffmanCodeWord(&codeLenCodeTab)) == EOF)
  3137.       goto err;
  3138.     if (code == 16) {
  3139.       if ((repeat = getCodeWord(2)) == EOF)
  3140.     goto err;
  3141.       for (repeat += 3; repeat > 0; --repeat)
  3142.     allCodes[i++].len = len;
  3143.     } else if (code == 17) {
  3144.       if ((repeat = getCodeWord(3)) == EOF)
  3145.     goto err;
  3146.       len = 0;
  3147.       for (repeat += 3; repeat > 0; --repeat)
  3148.     allCodes[i++].len = 0;
  3149.     } else if (code == 18) {
  3150.       if ((repeat = getCodeWord(7)) == EOF)
  3151.     goto err;
  3152.       len = 0;
  3153.       for (repeat += 11; repeat > 0; --repeat)
  3154.     allCodes[i++].len = 0;
  3155.     } else {
  3156.       allCodes[i++].len = len = code;
  3157.     }
  3158.   }
  3159.   compHuffmanCodes(&litCodeTab, numLitCodes);
  3160.   compHuffmanCodes(&distCodeTab, numDistCodes);
  3161.  
  3162.   return gTrue;
  3163.  
  3164. err:
  3165.   error(getPos(), R_BAD_DYNAMIC_CODE_TABLE_IN_FLATE_STREAM);
  3166.   return gFalse;
  3167. }
  3168.  
  3169. // On entry, the <tab->codes> array contains the lengths of each code,
  3170. // stored in code value order.  This function computes the code words.
  3171. // The result is sorted in order of (1) code length and (2) code word.
  3172. // The length values are no longer valid.  The <tab->start> array is
  3173. // filled with the indexes of the first code of each length.
  3174. void FlateStream::compHuffmanCodes(FlateHuffmanTab *tab, int n) {
  3175.   int numLengths[flateMaxHuffman+1];
  3176.   int nextCode[flateMaxHuffman+1];
  3177.   int nextIndex[flateMaxHuffman+2];
  3178.   int code;
  3179.   int i, j;
  3180.  
  3181.   // count number of codes for each code length
  3182.   for (i = 0; i <= flateMaxHuffman; ++i)
  3183.     numLengths[i] = 0;
  3184.   for (i = 0; i < n; ++i)
  3185.     ++numLengths[tab->codes[i].len];
  3186.  
  3187.   // compute first index for each length
  3188.   tab->start[0] = nextIndex[0] = 0;
  3189.   for (i = 1; i <= flateMaxHuffman + 1; ++i)
  3190.     tab->start[i] = nextIndex[i] = tab->start[i-1] + numLengths[i-1];
  3191.  
  3192.   // compute first code for each length
  3193.   code = 0;
  3194.   numLengths[0] = 0;
  3195.   for (i = 1; i <= flateMaxHuffman; ++i) {
  3196.     code = (code + numLengths[i-1]) << 1;
  3197.     nextCode[i] = code;
  3198.   }
  3199.  
  3200.   // compute the codes -- this permutes the codes array from value
  3201.   // order to length/code order
  3202.   for (i = 0; i < n; ++i) {
  3203.     j = nextIndex[tab->codes[i].len]++;
  3204.     if (tab->codes[i].len == 0)
  3205.       tab->codes[j].code = 0;
  3206.     else
  3207.       tab->codes[j].code = nextCode[tab->codes[i].len]++;
  3208.     tab->codes[j].val = i;
  3209.   }
  3210. }
  3211.  
  3212. int FlateStream::getHuffmanCodeWord(FlateHuffmanTab *tab) {
  3213.   int len;
  3214.   int code;
  3215.   int c;
  3216.   int i, j;
  3217.  
  3218.   code = 0;
  3219.   for (len = 1; len <= flateMaxHuffman; ++len) {
  3220.  
  3221.     // add a bit to the code
  3222.     if (codeSize == 0) {
  3223.       if ((c = str->getChar()) == EOF)
  3224.     return EOF;
  3225.       codeBuf = c & 0xff;
  3226.       codeSize = 8;
  3227.     }
  3228.     code = (code << 1) | (codeBuf & 1);
  3229.     codeBuf >>= 1;
  3230.     --codeSize;
  3231.  
  3232.     // look for code
  3233.     i = tab->start[len];
  3234.     j = tab->start[len + 1];
  3235.     if (i < j && code >= tab->codes[i].code && code <= tab->codes[j-1].code) {
  3236.       i += code - tab->codes[i].code;
  3237.       return tab->codes[i].val;
  3238.     }
  3239.   }
  3240.  
  3241.   // not found
  3242.   error(getPos(), R_BAD_CODE___04X__IN_FLATE_STREAM, code);
  3243.   return EOF;
  3244. }
  3245.  
  3246. int FlateStream::getCodeWord(int bits) {
  3247.   int c;
  3248.  
  3249.   while (codeSize < bits) {
  3250.     if ((c = str->getChar()) == EOF)
  3251.       return EOF;
  3252.     codeBuf |= (c & 0xff) << codeSize;
  3253.     codeSize += 8;
  3254.   }
  3255.   c = codeBuf & ((1 << bits) - 1);
  3256.   codeBuf >>= bits;
  3257.   codeSize -= bits;
  3258.   return c;
  3259. }
  3260.  
  3261. //------------------------------------------------------------------------
  3262. // EOFStream
  3263. //------------------------------------------------------------------------
  3264.  
  3265. EOFStream::EOFStream(Stream *str1) {
  3266.   str = str1;
  3267. }
  3268.  
  3269. EOFStream::~EOFStream() {
  3270.   delete str;
  3271. }
  3272.  
  3273. //------------------------------------------------------------------------
  3274. // FixedLengthEncoder
  3275. //------------------------------------------------------------------------
  3276.  
  3277. FixedLengthEncoder::FixedLengthEncoder(Stream *str1, int length1) {
  3278.   str = str1;
  3279.   length = length1;
  3280.   count = 0;
  3281. }
  3282.  
  3283. FixedLengthEncoder::~FixedLengthEncoder() {
  3284.   if (str->isEncoder())
  3285.     delete str;
  3286. }
  3287.  
  3288. void FixedLengthEncoder::reset() {
  3289.   str->reset();
  3290.   count = 0;
  3291. }
  3292.  
  3293. int FixedLengthEncoder::getChar() {
  3294.   if (length >= 0 && count >= length)
  3295.     return EOF;
  3296.   ++count;
  3297.   return str->getChar();
  3298. }
  3299.  
  3300. int FixedLengthEncoder::lookChar() {
  3301.   if (length >= 0 && count >= length)
  3302.     return EOF;
  3303.   return str->getChar();
  3304. }
  3305.  
  3306. //------------------------------------------------------------------------
  3307. // ASCII85Encoder
  3308. //------------------------------------------------------------------------
  3309.  
  3310. ASCII85Encoder::ASCII85Encoder(Stream *str1) {
  3311.   str = str1;
  3312.   bufPtr = bufEnd = buf;
  3313.   lineLen = 0;
  3314.   eof = gFalse;
  3315. }
  3316.  
  3317. ASCII85Encoder::~ASCII85Encoder() {
  3318.   if (str->isEncoder())
  3319.     delete str;
  3320. }
  3321.  
  3322. void ASCII85Encoder::reset() {
  3323.   str->reset();
  3324.   bufPtr = bufEnd = buf;
  3325.   lineLen = 0;
  3326.   eof = gFalse;
  3327. }
  3328.  
  3329. #if 0
  3330. int  ASCII85Encoder::getChar() { 
  3331.   if (bufPtr<bufEnd)
  3332.     return (*bufPtr++ & 0xff);
  3333.   if (fillBuf()) 
  3334.     return (*bufPtr++ & 0xff); 
  3335.   return EOF;
  3336.   //return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff); 
  3337.   //return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff); 
  3338. }
  3339.  
  3340. int  ASCII85Encoder::lookChar() { 
  3341.   if (bufPtr<bufEnd)
  3342.     return (*bufPtr & 0xff);
  3343.   if (fillBuf()) 
  3344.     return (*bufPtr & 0xff); 
  3345.   return EOF;
  3346.   //return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr & 0xff); 
  3347.   //return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr & 0xff); 
  3348. }
  3349. #endif
  3350.  
  3351. GBool ASCII85Encoder::fillBuf() {
  3352.   Gulong t;
  3353.   char buf1[5];
  3354.   register int c;
  3355.   register int n, i;
  3356.  
  3357.   if (eof)
  3358.     return gFalse;
  3359.   t = 0;
  3360.   for (n = 0; n < 4; ++n) {
  3361.     if ((c = str->getChar()) == EOF)
  3362.       break;
  3363.     t = (t << 8) + c;
  3364.   }
  3365.   bufPtr = bufEnd = buf;
  3366.   if (n > 0) {
  3367.     if (n == 4 && t == 0) {
  3368.       *bufEnd++ = 'z';
  3369.       if (++lineLen == 65) {
  3370.     *bufEnd++ = '\n';
  3371.     lineLen = 0;
  3372.       }
  3373.     } else {
  3374.       if (n < 4)
  3375.     t <<= 8 * (4 - n);
  3376.       for (i = 4; i >= 0; --i) {
  3377.     buf1[i] = (char)(t % 85 + 0x21);
  3378.     t /= 85;
  3379.       }
  3380.       for (i = 0; i <= n; ++i) {
  3381.     *bufEnd++ = buf1[i];
  3382.     if (++lineLen == 65) {
  3383.       *bufEnd++ = '\n';
  3384.       lineLen = 0;
  3385.     }
  3386.       }
  3387.     }
  3388.   }
  3389.   if (n < 4) {
  3390.     *bufEnd++ = '~';
  3391.     *bufEnd++ = '>';
  3392.     eof = gTrue;
  3393.   }
  3394.   return bufPtr < bufEnd;
  3395. }
  3396.  
  3397. //------------------------------------------------------------------------
  3398. // RunLengthEncoder
  3399. //------------------------------------------------------------------------
  3400.  
  3401. RunLengthEncoder::RunLengthEncoder(Stream *str1) {
  3402.   str = str1;
  3403.   bufPtr = bufEnd = nextEnd = buf;
  3404.   eof = gFalse;
  3405. }
  3406.  
  3407. RunLengthEncoder::~RunLengthEncoder() {
  3408.   if (str->isEncoder())
  3409.     delete str;
  3410. }
  3411.  
  3412. void RunLengthEncoder::reset() {
  3413.   str->reset();
  3414.   bufPtr = bufEnd = nextEnd = buf;
  3415.   eof = gFalse;
  3416. }
  3417.  
  3418. #if 0
  3419. int RunLengthEncoder::getChar()
  3420.   if (bufPtr<bufEnd)
  3421.     return (*bufPtr++ & 0xff);
  3422.   if (fillBuf()) 
  3423.     return (*bufPtr++ & 0xff); 
  3424.   return EOF;
  3425.   //return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff); 
  3426.   //return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff); 
  3427. }
  3428.  
  3429. int RunLengthEncoder::lookChar()
  3430.   if (bufPtr<bufEnd)
  3431.     return (*bufPtr & 0xff);
  3432.   if (fillBuf()) 
  3433.     return (*bufPtr & 0xff); 
  3434.   return EOF;
  3435.   //return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr & 0xff); 
  3436.   //return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr & 0xff); 
  3437. }
  3438. #endif
  3439.  
  3440. //
  3441. // When fillBuf finishes, buf[] looks like this:
  3442. //   +-----+--------------+-----------------+--
  3443. //   + tag | ... data ... | next 0, 1, or 2 |
  3444. //   +-----+--------------+-----------------+--
  3445. //    ^                    ^                 ^
  3446. //    bufPtr               bufEnd            nextEnd
  3447. //
  3448. GBool RunLengthEncoder::fillBuf() {
  3449.   int c, c1, c2;
  3450.   int n;
  3451.  
  3452.   // already hit EOF?
  3453.   if (eof)
  3454.     return gFalse;
  3455.  
  3456.   // grab two bytes
  3457.   if (nextEnd < bufEnd + 1) {
  3458.     if ((c1 = str->getChar()) == EOF) {
  3459.       eof = gTrue;
  3460.       return gFalse;
  3461.     }
  3462.   } else {
  3463.     c1 = bufEnd[0] & 0xff;
  3464.   }
  3465.   if (nextEnd < bufEnd + 2) {
  3466.     if ((c2 = str->getChar()) == EOF) {
  3467.       eof = gTrue;
  3468.       buf[0] = 0;
  3469.       buf[1] = c1;
  3470.       bufPtr = buf;
  3471.       bufEnd = &buf[2];
  3472.       return gTrue;
  3473.     }
  3474.   } else {
  3475.     c2 = bufEnd[1] & 0xff;
  3476.   }
  3477.  
  3478.   // check for repeat
  3479.   c = 0; // make gcc happy
  3480.   if (c1 == c2) {
  3481.     n = 2;
  3482.     while (n < 128 && (c = str->getChar()) == c1)
  3483.       ++n;
  3484.     buf[0] = (char)(257 - n);
  3485.     buf[1] = c1;
  3486.     bufEnd = &buf[2];
  3487.     if (c == EOF) {
  3488.       eof = gTrue;
  3489.     } else if (n < 128) {
  3490.       buf[2] = c;
  3491.       nextEnd = &buf[3];
  3492.     } else {
  3493.       nextEnd = bufEnd;
  3494.     }
  3495.  
  3496.   // get up to 128 chars
  3497.   } else {
  3498.     buf[1] = c1;
  3499.     buf[2] = c2;
  3500.     n = 2;
  3501.     while (n < 128) {
  3502.       if ((c = str->getChar()) == EOF) {
  3503.     eof = gTrue;
  3504.     break;
  3505.       }
  3506.       ++n;
  3507.       buf[n] = c;
  3508.       if (buf[n] == buf[n-1])
  3509.     break;
  3510.     }
  3511.     if (buf[n] == buf[n-1]) {
  3512.       buf[0] = (char)(n-2-1);
  3513.       bufEnd = &buf[n-1];
  3514.       nextEnd = &buf[n+1];
  3515.     } else {
  3516.       buf[0] = (char)(n-1);
  3517.       bufEnd = nextEnd = &buf[n+1];
  3518.     }
  3519.   }
  3520.   bufPtr = buf;
  3521.   return gTrue;
  3522. }
  3523.