home *** CD-ROM | disk | FTP | other *** search
/ PD Collection CD 1 / PD Collection CD 1.iso / textual / pdftops / xpdf / c++ / Stream < prev    next >
Encoding:
Text File  |  1996-06-09  |  35.4 KB  |  1,660 lines

  1. //========================================================================
  2. //
  3. // Stream.cc
  4. //
  5. // Copyright 1996 Derek B. Noonburg
  6. //
  7. //========================================================================
  8.  
  9. #ifdef __GNUC__
  10. //#pragma implementation
  11. #endif
  12.  
  13. #include <stdio.h>
  14. #include <stdlib.h>
  15. #include <stddef.h>
  16. #include "unistd.h"
  17. #include <string.h>
  18. #include <ctype.h>
  19. #include "gmem.h"
  20. #include "config.h"
  21. #include "Error.h"
  22. #include "Object.h"
  23. #include "Stream.h"
  24. #include "Stream-CCITT.h"
  25.  
  26. #ifdef VMS
  27. extern "C" int unlink(char *filename);
  28. #ifdef __GNUC__
  29. #define SEEK_SET 0
  30. #define SEEK_CUR 1
  31. #define SEEK_END 2
  32. #endif
  33. #endif
  34.  
  35. //------------------------------------------------------------------------
  36.  
  37. #define headerSearchSize 1024    // read this many bytes at beginning of
  38.                 //   file to look for '%PDF'
  39. //------------------------------------------------------------------------
  40. // Stream (base class)
  41. //------------------------------------------------------------------------
  42.  
  43. void Stream::setPos(int pos) {
  44.   error(0, "Internal: called setPos() on non-FileStream");
  45. }
  46.  
  47. GString *Stream::getPSFilter(char *indent) {
  48.   return new GString();
  49. }
  50.  
  51. Stream *Stream::addFilters(Object *dict) {
  52.   Object obj, obj2;
  53.   Object params, params2;
  54.   Stream *str;
  55.   int i;
  56.  
  57.   str = this;
  58.   dict->dictLookup("Filter", &obj);
  59.   if (obj.isNull()) {
  60.     obj.free();
  61.     dict->dictLookup("F", &obj);
  62.   }
  63.   dict->dictLookup("DecodeParms", ¶ms);
  64.   if (params.isNull()) {
  65.     params.free();
  66.     dict->dictLookup("DP", ¶ms);
  67.   }
  68.   if (obj.isName()) {
  69.     str = makeFilter(obj.getName(), str, ¶ms);
  70.   } else if (obj.isArray()) {
  71.     for (i = 0; i < obj.arrayGetLength(); ++i) {
  72.       obj.arrayGet(i, &obj2);
  73.       if (params.isArray())
  74.     params.arrayGet(i, ¶ms2);
  75.       else
  76.     params2.initNull();
  77.       if (obj2.isName())
  78.     str = makeFilter(obj2.getName(), str, ¶ms2);
  79.       else
  80.     error(getPos(), "Bad filter name");
  81.       obj2.free();
  82.       params2.free();
  83.     }
  84.   } else if (!obj.isNull()) {
  85.     error(getPos(), "Bad 'Filter' attribute in stream");
  86.   }
  87.   obj.free();
  88.   params.free();
  89.  
  90.   return str;
  91. }
  92.  
  93. Stream *Stream::makeFilter(char *name, Stream *str, Object *params) {
  94.   int predictor;        // parameters
  95.   int colors;
  96.   int bits;
  97.   int early;
  98.   int encoding;
  99.   GBool byteAlign;
  100.   GBool black;
  101.   int columns, rows;
  102.   Object obj;
  103.  
  104.   if (!strcmp(name, "ASCIIHexDecode") || !strcmp(name, "AHx")) {
  105.     str = new ASCIIHexStream(str);
  106.   } else if (!strcmp(name, "ASCII85Decode") || !strcmp(name, "A85")) {
  107.     str = new ASCII85Stream(str);
  108.   } else if (!strcmp(name, "LZWDecode") || !strcmp(name, "LZW")) {
  109.     predictor = 1;
  110.     columns = 1;
  111.     colors = 1;
  112.     bits = 8;
  113.     early = 1;
  114.     if (params->isDict()) {
  115.       params->dictLookup("Predictor", &obj);
  116.       if (obj.isInt())
  117.     predictor = obj.getInt();
  118.       obj.free();
  119.       params->dictLookup("Columns", &obj);
  120.       if (obj.isInt())
  121.     columns = obj.getInt();
  122.       obj.free();
  123.       params->dictLookup("Colors", &obj);
  124.       if (obj.isInt())
  125.     colors = obj.getInt();
  126.       obj.free();
  127.       params->dictLookup("BitsPerComponent", &obj);
  128.       if (obj.isInt())
  129.     bits = obj.getInt();
  130.       obj.free();
  131.       params->dictLookup("EarlyChange", &obj);
  132.       if (obj.isInt())
  133.     early = obj.getInt();
  134.       obj.free();
  135.     }
  136.     str = new LZWStream(str, predictor, columns, colors, bits, early);
  137. //~  } else if (!strcmp(name, "RunLengthDecode")) {
  138.   } else if (!strcmp(name, "CCITTFaxDecode")) {
  139.     encoding = 0;
  140.     byteAlign = gFalse;
  141.     columns = 1728;
  142.     rows = 0;
  143.     black = gFalse;
  144.     if (params->isDict()) {
  145.       params->dictLookup("K", &obj);
  146.       if (obj.isInt())
  147.     encoding = obj.getInt();
  148.       obj.free();
  149.       params->dictLookup("EncodedByteAlign", &obj);
  150.       if (obj.isBool())
  151.     byteAlign = obj.getBool();
  152.       obj.free();
  153.       params->dictLookup("Columns", &obj);
  154.       if (obj.isInt())
  155.     columns = obj.getInt();
  156.       obj.free();
  157.       params->dictLookup("Rows", &obj);
  158.       if (obj.isInt())
  159.     rows = obj.getInt();
  160.       obj.free();
  161.       params->dictLookup("BlackIs1", &obj);
  162.       if (obj.isBool())
  163.     black = obj.getBool();
  164.       obj.free();
  165.     }
  166.     str = new CCITTFaxStream(str, encoding, byteAlign, columns, rows, black);
  167.   } else if (!strcmp(name, "DCTDecode")) {
  168.     str = new DCTStream(str);
  169.   } else {
  170.     error(getPos(), "Unknown filter '%s'", name);
  171.   }
  172.   return str;
  173. }
  174.  
  175. //------------------------------------------------------------------------
  176. // FileStream
  177. //------------------------------------------------------------------------
  178.  
  179. FileStream::FileStream(FILE *f1, int start1, int length1, Object *dict1) {
  180.   f = f1;
  181.   start = start1;
  182.   length = length1;
  183.   pos = start;
  184.   savePos = -1;
  185.   dict = *dict1;
  186. }
  187.  
  188. FileStream::~FileStream() {
  189.   if (savePos >= 0)
  190.     fseek(f, savePos, SEEK_SET);
  191.   dict.free();
  192. }
  193.  
  194. void FileStream::reset() {
  195.   savePos = ftell(f);
  196.   fseek(f, start, SEEK_SET);
  197.   pos = start;
  198. }
  199.  
  200. int FileStream::getChar() {
  201.   int c;
  202.  
  203.   if (length >= 0 && pos >= start + length)
  204.     return EOF;
  205.   c = fgetc(f);
  206.   if (c != EOF)
  207.     ++pos;
  208.   return c;
  209. }
  210.  
  211. void FileStream::setPos(int pos1) {
  212.   if (pos1 >= 0) {
  213.     fseek(f, pos1, SEEK_SET);
  214.     pos = pos1;
  215.   } else {
  216.     fseek(f, pos1, SEEK_END);
  217.     pos = ftell(f);
  218.   }
  219. }
  220.  
  221. GBool FileStream::checkHeader() {
  222.   char buf[headerSearchSize+1];
  223.   char *p;
  224.   double version;
  225.   int i;
  226.  
  227.   for (i = 0; i < headerSearchSize; ++i)
  228.     buf[i] = getChar();
  229.   buf[headerSearchSize] = '\0';
  230.   for (i = 0; i < headerSearchSize - 5; ++i) {
  231.     if (!strncmp(&buf[i], "%PDF-", 5))
  232.       break;
  233.   }
  234.   if (i >= headerSearchSize - 5) {
  235.     error(0, "May not be a PDF file (continuing anyway)");
  236.     return gFalse;
  237.   }
  238.   start += i;
  239.   p = strtok(&buf[i+5], " \t\n\r");
  240.   version = atof(p);
  241.   if (!(buf[i+5] >= '0' && buf[i+5] <= '9') || version > pdfVersionNum) {
  242.     error(getPos(), "PDF version %s -- xpdf supports version %s"
  243.       " (continuing anyway)", p, pdfVersion);
  244.     return gFalse;
  245.   }
  246.   return gTrue;
  247. }
  248.  
  249. //------------------------------------------------------------------------
  250. // SubStream
  251. //------------------------------------------------------------------------
  252.  
  253. SubStream::SubStream(Stream *str1, Object *dict1) {
  254.   str = str1;
  255.   dict = *dict1;
  256. }
  257.  
  258. SubStream::~SubStream() {
  259.   dict.free();
  260. }
  261.  
  262. //------------------------------------------------------------------------
  263. // ASCIIHexStream
  264. //------------------------------------------------------------------------
  265.  
  266. ASCIIHexStream::ASCIIHexStream(Stream *str1) {
  267.   str = str1;
  268.   eof = gFalse;
  269. }
  270.  
  271. ASCIIHexStream::~ASCIIHexStream() {
  272.   delete str;
  273. }
  274.  
  275. void ASCIIHexStream::reset() {
  276.   str->reset();
  277.   eof = gFalse;
  278. }
  279.  
  280. int ASCIIHexStream::getChar() {
  281.   int c1, c2, x;
  282.  
  283.   if (eof)
  284.     return EOF;
  285.   do {
  286.     c1 = str->getChar();
  287.   } while (isspace(c1));
  288.   if (c1 == '>') {
  289.     eof = gTrue;
  290.     return EOF;
  291.   }
  292.   do {
  293.     c2 = str->getChar();
  294.   } while (isspace(c2));
  295.   if (c2 == '>') {
  296.     eof = gTrue;
  297.     c2 = '0';
  298.   }
  299.   if (c1 >= '0' && c1 <= '9') {
  300.     x = (c1 - '0') << 4;
  301.   } else if (c1 >= 'A' && c1 <= 'F') {
  302.     x = (c1 - 'A' + 10) << 4;
  303.   } else if (c1 >= 'a' && c1 <= 'f') {
  304.     x = (c1 - 'a' + 10) << 4;
  305.   } else {
  306.     error(getPos(), "Illegal character <%02x> in ASCIIHex stream", c1);
  307.     x = 0;
  308.   }
  309.   if (c2 >= '0' && c2 <= '9') {
  310.     x += c2 - '0';
  311.   } else if (c2 >= 'A' && c2 <= 'F') {
  312.     x += c2 - 'A' + 10;
  313.   } else if (c2 >= 'a' && c2 <= 'f') {
  314.     x += c2 - 'a' + 10;
  315.   } else {
  316.     error(getPos(), "Illegal character <%02x> in ASCIIHex stream", c2);
  317.   }
  318.   return x & 0xff;
  319. }
  320.  
  321. GString *ASCIIHexStream::getPSFilter(char *indent) {
  322.   GString *s;
  323.  
  324.   s = str->getPSFilter(indent);
  325.   s->append(indent)->append("/ASCIIHexDecode filter\n");
  326.   return s;
  327. }
  328.  
  329. GBool ASCIIHexStream::isBinary(GBool last) {
  330.   return str->isBinary(gFalse);
  331. }
  332.  
  333. //------------------------------------------------------------------------
  334. // ASCII85Stream
  335. //------------------------------------------------------------------------
  336.  
  337. ASCII85Stream::ASCII85Stream(Stream *str1) {
  338.   str = str1;
  339.   index = n = 0;
  340.   eof = gFalse;
  341. }
  342.  
  343. ASCII85Stream::~ASCII85Stream() {
  344.   delete str;
  345. }
  346.  
  347. void ASCII85Stream::reset() {
  348.   str->reset();
  349.   index = n = 0;
  350.   eof = gFalse;
  351. }
  352.  
  353. int ASCII85Stream::getChar() {
  354.   int k;
  355.   Gulong t;
  356.  
  357.   if (index >= n) {
  358.     if (eof)
  359.       return EOF;
  360.     index = 0;
  361.     do {
  362.       c[0] = str->getChar();
  363.     } while (c[0] == '\n' || c[0] == '\r');
  364.     if (c[0] == '~') {
  365.       eof = gTrue;
  366.       n = 0;
  367.       return EOF;
  368.     } else if (c[0] == 'z') {
  369.       b[0] = b[1] = b[2] = b[3] = 0;
  370.       n = 4;
  371.     } else {
  372.       for (k = 1; k < 5; ++k) {
  373.     do {
  374.       c[k] = str->getChar();
  375.     } while (c[k] == '\n' || c[k] == '\r');
  376.     if (c[k] == '~')
  377.       break;
  378.       }
  379.       n = k - 1;
  380.       if (k < 5 && c[k] == '~') {
  381.     for (++k; k < 5; ++k)
  382.       c[k] = 0x21;
  383.     eof = gTrue;
  384.       }
  385.       t = 0;
  386.       for (k = 0; k < 5; ++k)
  387.     t = t * 85 + (c[k] - 0x21);
  388.       for (k = 3; k >= 0; --k) {
  389.     b[k] = t & 0xff;
  390.     t >>= 8;
  391.       }
  392.     }
  393.   }
  394.   return b[index++];
  395. }
  396.  
  397. GString *ASCII85Stream::getPSFilter(char *indent) {
  398.   GString *s;
  399.  
  400.   s = str->getPSFilter(indent);
  401.   s->append(indent)->append("/ASCII85Decode filter\n");
  402.   return s;
  403. }
  404.  
  405. GBool ASCII85Stream::isBinary(GBool last) {
  406.   return str->isBinary(gFalse);
  407. }
  408.  
  409. //------------------------------------------------------------------------
  410. // LZWStream
  411. //------------------------------------------------------------------------
  412.  
  413. LZWStream::LZWStream(Stream *str1, int predictor1, int columns1, int colors1,
  414.              int bits1, int early1) {
  415.   str = str1;
  416.   predictor = predictor1;
  417.   columns = columns1;
  418.   colors = colors1;
  419.   bits = bits1;
  420.   early = early1;
  421.   zPipe = NULL;
  422. }
  423.  
  424. LZWStream::~LZWStream() {
  425.   if (zPipe) {
  426. #ifdef NO_POPEN
  427.     fclose(zPipe);
  428. #else
  429.     pclose(zPipe);
  430. #endif
  431.     zPipe = NULL;
  432.     unlink(zName);
  433.   }
  434.   delete str;
  435. }
  436.  
  437. void LZWStream::reset() {
  438.   FILE *f;
  439. #ifdef __riscos
  440. // snb94r@ecs.soton.ac.uk modified this function greatly to decompress
  441. // stuff into <Wimp$ScrapDir> and get around the pickyness of gzip over
  442. // filenames.
  443.   char sndtmp[256];
  444. #endif
  445.   str->reset();
  446.   if (zPipe) {
  447. #ifdef NO_POPEN
  448.     fclose(zPipe);
  449. #else
  450.     pclose(zPipe);
  451. #endif
  452.     zPipe = NULL;
  453.     unlink(zName);
  454.   }
  455.   strcpy(zCmd, uncompressCmd);
  456.   strcat(zCmd, " ");
  457.   zName = zCmd + strlen(zCmd);
  458.   tmpnam(zName);
  459.   #ifdef __riscos
  460.   strcpy(sndtmp, zName);
  461.   sprintf(&zName[strlen(zName)-3], "/gz");
  462.   #else
  463.   strcat(zName, ".Z");
  464.   #endif
  465.   if (!(f = fopen(zName, "w"))) {
  466.     error(getPos(), "Couldn't open temporary file '%s'", zName);
  467.     return;
  468.   }
  469.   dumpFile(f);
  470.   fclose(f);
  471. #ifdef NO_POPEN
  472. #ifdef VMS
  473.   if (!system(zCmd)) {
  474. #else
  475.   if (system(zCmd)) {
  476. #endif
  477.     error(getPos(), "Couldn't execute '%s'", zCmd);
  478.     unlink(zName);
  479.     return;
  480.   }
  481.   #ifdef __riscos
  482.   zName[strlen(zName)-3] = 0;
  483.   rename(zName, sndtmp);
  484.   strcpy(zName, sndtmp);
  485.   #else
  486.   zName[strlen(zName) - 2] = '\0';
  487.   #endif
  488.   if (!(zPipe = fopen(zName, "r"))) {
  489.     error(getPos(), "Couldn't open uncompress file '%s'", zName);
  490.     unlink(zName);
  491.     return;
  492.   }
  493. #else
  494.   if (!(zPipe = popen(zCmd, "r"))) {
  495.     error(getPos(), "Couldn't popen '%s'", zCmd);
  496.     unlink(zName);
  497.     return;
  498.   }
  499. #endif
  500. }
  501.  
  502. void LZWStream::dumpFile(FILE *f) {
  503.   int outCodeBits;        // size of output code
  504.   int outBits;            // max output code
  505.   int outBuf[8];        // output buffer
  506.   int outData;            // temporary output buffer
  507.   int inCode, outCode;        // input and output codes
  508.   int nextCode;            // next code index
  509.   GBool eof;            // set when EOF is reached
  510.   GBool clear;            // set if table needs to be cleared
  511.   GBool first;            // indicates first code word after clear
  512.   int i, j;
  513.  
  514.   // magic number
  515.   fputc(0x1f, f);
  516.   fputc(0x9d, f);
  517.  
  518.   // max code length, block mode flag
  519.   fputc(0x8c, f);
  520.  
  521.   // init input side
  522.   inCodeBits = 9;
  523.   inputBuf = 0;
  524.   inputBits = 0;
  525.   eof = gFalse;
  526.  
  527.   // init output side
  528.   outCodeBits = 9;
  529.  
  530.   // clear table
  531.   first = gTrue;
  532.   nextCode = 258;
  533.  
  534.   clear = gFalse;
  535.   do {
  536.     for (i = 0; i < 8; ++i) {
  537.       // check for table overflow
  538.       if (nextCode + early > 0x1001) {
  539.     inCode = 256;
  540.  
  541.       // read input code
  542.       } else {
  543.     do {
  544.       inCode = getCode();
  545.       if (inCode == EOF) {
  546.         eof = gTrue;
  547.         inCode = 0;
  548.       }
  549.     } while (first && inCode == 256);
  550.       }
  551.  
  552.       // compute output code
  553.       if (inCode < 256) {
  554.     outCode = inCode;
  555.       } else if (inCode == 256) {
  556.     outCode = 256;
  557.     clear = gTrue;
  558.       } else if (inCode == 257) {
  559.     outCode = 0;
  560.     eof = gTrue;
  561.       } else {
  562.     outCode = inCode - 1;
  563.       }
  564.       outBuf[i] = outCode;
  565.  
  566.       // next code index
  567.       if (first)
  568.     first = gFalse;
  569.       else
  570.     ++nextCode;
  571.  
  572.       // check input code size
  573.       if (nextCode + early == 0x200)
  574.     inCodeBits = 10;
  575.       else if (nextCode + early == 0x400) {
  576.     inCodeBits = 11;
  577.       } else if (nextCode + early == 0x800) {
  578.     inCodeBits = 12;
  579.       }
  580.  
  581.       // check for eof/clear
  582.       if (eof)
  583.     break;
  584.       if (clear) {
  585.     i = 8;
  586.     break;
  587.       }
  588.     }
  589.  
  590.     // write output block
  591.     outData = 0;
  592.     outBits = 0;
  593.     j = 0;
  594.     while (j < i || outBits > 0) {
  595.       if (outBits < 8 && j < i) {
  596.     outData = outData | (outBuf[j++] << outBits);
  597.     outBits += outCodeBits;
  598.       }
  599.       fputc(outData & 0xff, f);
  600.       outData >>= 8;
  601.       outBits -= 8;
  602.     }
  603.  
  604.     // check output code size
  605.     if (nextCode - 1 == 512 ||
  606.     nextCode - 1 == 1024 ||
  607.     nextCode - 1 == 2048 ||
  608.     nextCode - 1 == 4096) {
  609.       outCodeBits = inCodeBits;
  610.     }
  611.  
  612.     // clear table if necessary
  613.     if (clear) {
  614.       inCodeBits = 9;
  615.       outCodeBits = 9;
  616.       first = gTrue;
  617.       nextCode = 258;
  618.       clear = gFalse;
  619.     }
  620.   } while (!eof);
  621. }
  622.  
  623. int LZWStream::getCode() {
  624.   int c;
  625.   int code;
  626.  
  627.   while (inputBits < inCodeBits) {
  628.     if ((c = str->getChar()) == EOF)
  629.       return EOF;
  630.     inputBuf = (inputBuf << 8) | (c & 0xff);
  631.     inputBits += 8;
  632.   }
  633.   code = (inputBuf >> (inputBits - inCodeBits)) & ((1 << inCodeBits) - 1);
  634.   inputBits -= inCodeBits;
  635.   return code;
  636. }
  637.  
  638. int LZWStream::getChar() {
  639.   int c;
  640.  
  641.   if (!zPipe)
  642.     return EOF;
  643.   if ((c = fgetc(zPipe)) == EOF) {
  644. #ifdef NO_POPEN
  645.     fclose(zPipe);
  646. #else
  647.     pclose(zPipe);
  648. #endif
  649.     zPipe = NULL;
  650.     unlink(zName);
  651.   }
  652.   return c;
  653. }
  654.  
  655. GString *LZWStream::getPSFilter(char *indent) {
  656.   GString *s;
  657.  
  658.   s = str->getPSFilter(indent);
  659.   s->append(indent)->append("/LZWDecode filter\n");
  660.   return s;
  661. }
  662.  
  663. GBool LZWStream::isBinary(GBool last) {
  664.   return str->isBinary(gTrue);
  665. }
  666.  
  667. //------------------------------------------------------------------------
  668. // CCITTFaxStream
  669. //------------------------------------------------------------------------
  670.  
  671. CCITTFaxStream::CCITTFaxStream(Stream *str1, int encoding1, GBool byteAlign1,
  672.                    int columns1, int rows1, GBool black1) {
  673.   str = str1;
  674.   encoding = encoding1;
  675.   byteAlign = byteAlign1;
  676.   columns = columns1;
  677.   rows = rows1;
  678.   black = black1;
  679.   refLine = (short *)gmalloc((columns + 2) * sizeof(short));
  680.   codingLine = (short *)gmalloc((columns + 2) * sizeof(short));
  681.  
  682.   eof = gFalse;
  683.   inputBits = 0;
  684.   codingLine[0] = 0;
  685.   codingLine[1] = refLine[2] = columns;
  686.   a0 = 1;
  687. }
  688.  
  689. CCITTFaxStream::~CCITTFaxStream() {
  690.   delete str;
  691.   gfree(refLine);
  692.   gfree(codingLine);
  693. }
  694.  
  695. void CCITTFaxStream::reset() {
  696.   str->reset();
  697.   eof = gFalse;
  698.   inputBits = 0;
  699.   codingLine[0] = 0;
  700.   codingLine[1] = refLine[2] = columns;
  701.   a0 = 1;
  702. }
  703.  
  704. int CCITTFaxStream::getChar() {
  705.   short code1, code2;
  706.   int a0New;
  707.   int ret;
  708.   int bits, i;
  709.  
  710.   // if at eof just return EOF
  711.   if (eof && codingLine[a0] >= columns)
  712.     return EOF;
  713.  
  714.   // read the next row
  715.   if (codingLine[a0] >= columns) {
  716.     for (i = 0; codingLine[i] < columns; ++i)
  717.       refLine[i] = codingLine[i];
  718.     refLine[i] = refLine[i + 1] = columns;
  719.     b1 = 1;
  720.     a0New = codingLine[a0 = 0] = 0;
  721.     do {
  722.       code1 = getCode(twoDimTable);
  723.       switch (code1) {
  724.       case twoDimPass:
  725.     if (refLine[b1] < columns) {
  726.       a0New = refLine[b1 + 1];
  727.       b1 += 2;
  728.     }
  729.     break;
  730.       case twoDimHoriz:
  731.     if ((a0 & 1) == 0) {
  732.       if ((code1 = getCode(whiteTable)) >= 64)
  733.         code1 += getCode(whiteTable);
  734.       if ((code2 = getCode(blackTable)) >= 64)
  735.         code2 += getCode(blackTable);
  736.     } else {
  737.       if ((code1 = getCode(blackTable)) >= 64)
  738.         code1 += getCode(blackTable);
  739.       if ((code2 = getCode(whiteTable)) >= 64)
  740.         code2 += getCode(whiteTable);
  741.     }
  742.     codingLine[a0 + 1] = a0New + code1;
  743.     ++a0;
  744.     a0New = codingLine[a0 + 1] = codingLine[a0] + code2;
  745.     ++a0;
  746.     while (refLine[b1] <= codingLine[a0] && refLine[b1] < columns)
  747.       b1 += 2;
  748.     break;
  749.       case twoDimVert0:
  750.     a0New = codingLine[++a0] = refLine[b1];
  751.     if (refLine[b1] < columns) {
  752.       ++b1;
  753.       while (refLine[b1] <= codingLine[a0] && refLine[b1] < columns)
  754.         b1 += 2;
  755.     }
  756.     break;
  757.       case twoDimVertR1:
  758.     a0New = codingLine[++a0] = refLine[b1] + 1;
  759.     if (refLine[b1] < columns) {
  760.       ++b1;
  761.       while (refLine[b1] <= codingLine[a0] && refLine[b1] < columns)
  762.         b1 += 2;
  763.     }
  764.     break;
  765.       case twoDimVertL1:
  766.     a0New = codingLine[++a0] = refLine[b1] - 1;
  767.     --b1;
  768.     while (refLine[b1] <= codingLine[a0] && refLine[b1] < columns)
  769.       b1 += 2;
  770.     break;
  771.       case twoDimVertR2:
  772.     a0New = codingLine[++a0] = refLine[b1] + 2;
  773.     if (refLine[b1] < columns) {
  774.       ++b1;
  775.       while (refLine[b1] <= codingLine[a0] && refLine[b1] < columns)
  776.         b1 += 2;
  777.     }
  778.     break;
  779.       case twoDimVertL2:
  780.     a0New = codingLine[++a0] = refLine[b1] - 2;
  781.     --b1;
  782.     while (refLine[b1] <= codingLine[a0] && refLine[b1] < columns)
  783.       b1 += 2;
  784.     break;
  785.       case twoDimVertR3:
  786.     a0New = codingLine[++a0] = refLine[b1] + 3;
  787.     if (refLine[b1] < columns) {
  788.       ++b1;
  789.       while (refLine[b1] <= codingLine[a0] && refLine[b1] < columns)
  790.         b1 += 2;
  791.     }
  792.     break;
  793.       case twoDimVertL3:
  794.     a0New = codingLine[++a0] = refLine[b1] - 3;
  795.     --b1;
  796.     while (refLine[b1] <= codingLine[a0] && refLine[b1] < columns)
  797.       b1 += 2;
  798.     break;
  799.       case ccittEOL:
  800.     break;
  801.       case EOF:
  802.     eof = gTrue;
  803.     codingLine[a0 = 0] = columns;
  804.     return EOF;
  805.       default:
  806.     error(getPos(), "Bad 2D code %04x in CCITTFax stream", code1);
  807.     return EOF;
  808.       }
  809.     } while (codingLine[a0] < columns);
  810.     if (codingLine[a0] != columns)
  811.       error(getPos(), "CCITTFax row is wrong length (%d)", codingLine[a0]);
  812.     a0 = 0;
  813.     outputBits = codingLine[1] - codingLine[0];
  814.   }
  815.  
  816.   // get a byte
  817.   if (outputBits >= 8) {
  818.     ret = ((a0 & 1) == 0) ? 0xff : 0x00;
  819.     if ((outputBits -= 8) == 0) {
  820.       ++a0;
  821.       if (codingLine[a0] < columns)
  822.     outputBits = codingLine[a0 + 1] - codingLine[a0];
  823.     }
  824.   } else {
  825.     bits = 8;
  826.     ret = 0;
  827.     do {
  828.       if (outputBits > bits) {
  829.     i = bits;
  830.     bits = 0;
  831.     if ((a0 & 1) == 0)
  832.       ret |= 0xff >> (8 - i);
  833.     outputBits -= i;
  834.       } else {
  835.     i = outputBits;
  836.     bits -= outputBits;
  837.     if ((a0 & 1) == 0)
  838.       ret |= (0xff >> (8 - i)) << bits;
  839.     outputBits = 0;
  840.     ++a0;
  841.     if (codingLine[a0] < columns)
  842.       outputBits = codingLine[a0 + 1] - codingLine[a0];
  843.       }
  844.     } while (bits > 0 && codingLine[a0] < columns);
  845.   }
  846.   return black ? (ret ^ 0xff) : ret;
  847. }
  848.  
  849. short CCITTFaxStream::getCode(CCITTCodeTable *table) {
  850.   short code;
  851.   int codeBits, bit;
  852.   int a, b, m;
  853.  
  854.   code = 0;
  855.   codeBits = 0;
  856.   do {
  857.     // add a bit to the code
  858.     if ((bit = getBit()) == EOF)
  859.       return EOF;
  860.     code = (code << 1) + bit;
  861.     ++codeBits;
  862.  
  863.     // search code table
  864.     // invariant: codes[a].code < code < codes[b].code
  865.     if (table[codeBits].numCodes > 0) {
  866.       a = -1;
  867.       b = table[codeBits].numCodes;
  868.       m = 0;
  869.       while (b - a > 1) {
  870.     m = (a + b) / 2;
  871.     if (table[codeBits].codes[m].code < code)
  872.       a = m;
  873.     else if (table[codeBits].codes[m].code > code)
  874.       b = m;
  875.     else
  876.       a = b = m;
  877.       }
  878.       if (table[codeBits].codes[m].code == code)
  879.     return table[codeBits].codes[m].n;
  880.     }
  881.   } while (codeBits < ccittMaxCodeLen);
  882.  
  883.   error(getPos(), "Bad code (%04x) in CCITTFax stream", code);
  884.   return EOF;
  885. }
  886.  
  887. int CCITTFaxStream::getBit() {
  888.   int bit;
  889.   int c;
  890.  
  891.   if (inputBits == 0) {
  892.     if ((c = str->getChar()) == EOF)
  893.       return EOF;
  894.     inputBuf = c;
  895.     inputBits = 8;
  896.   }
  897.   bit = (inputBuf >> (inputBits - 1)) & 1;
  898.   --inputBits;
  899.   return bit;
  900. }
  901.  
  902. GString *CCITTFaxStream::getPSFilter(char *indent) {
  903.   GString *s;
  904.   char s1[50];
  905.  
  906.   s = str->getPSFilter(indent);
  907.   s->append(indent)->append("<< ");
  908.   if (encoding != 0) {
  909.     sprintf(s1, "/K %d ", encoding);
  910.     s->append(s1);
  911.   }
  912.   if (byteAlign)
  913.     s->append("/EncodedByteAlign true ");
  914.   sprintf(s1, "/Columns %d ", columns);
  915.   s->append(s1);
  916.   if (rows != 0) {
  917.     sprintf(s1, "/Rows %d ", rows);
  918.     s->append(s1);
  919.   }
  920.   if (black)
  921.     s->append("/BlackIs1 true ");
  922.   s->append(">> /CCITTFaxDecode filter\n");
  923.   return s;
  924. }
  925.  
  926. GBool CCITTFaxStream::isBinary(GBool last) {
  927.   return str->isBinary(gTrue);
  928. }
  929.  
  930. //------------------------------------------------------------------------
  931. // DCTStream
  932. //------------------------------------------------------------------------
  933.  
  934. #define dctCos1    0.98078528    // cos(pi/16)
  935. #define dctSin1    0.19509032    // sin(pi/16)
  936. #define dctCos3    0.83146961    // cos(3*pi/16)
  937. #define dctSin3    0.55557023    // sin(3*pi/16)
  938. #define dctCos6    0.38268343    // cos(6*pi/16)
  939. #define dctSin6    0.92387953    // sin(6*pi/16)
  940. #define dctSqrt2   1.41421356    // sqrt(2)
  941. #define dctSqrt1d2 0.70710678    // sqrt(2) / 2
  942.  
  943. #define dctCrToR   1.4020    // color conversion parameters
  944. #define dctCbToG  -0.3441363
  945. #define dctCrToG  -0.71413636
  946. #define dctCbToB   1.772
  947.  
  948. static int dctZigZag[64] = {
  949.    0,
  950.    1,  8,
  951.   16,  9,  2,
  952.    3, 10, 17, 24,
  953.   32, 25, 18, 11, 4,
  954.    5, 12, 19, 26, 33, 40,
  955.   48, 41, 34, 27, 20, 13,  6,
  956.    7, 14, 21, 28, 35, 42, 49, 56,
  957.   57, 50, 43, 36, 29, 22, 15,
  958.   23, 30, 37, 44, 51, 58,
  959.   59, 52, 45, 38, 31,
  960.   39, 46, 53, 60,
  961.   61, 54, 47,
  962.   55, 62,
  963.   63
  964. };
  965.  
  966. DCTStream::DCTStream(Stream *str1) {
  967.   int i, j;
  968.  
  969.   str = str1;
  970.   width = height = 0;
  971.   mcuWidth = mcuHeight = 0;
  972.   numComps = 0;
  973.   comp = 0;
  974.   x = y = dy = 0;
  975.   for (i = 0; i < 4; ++i)
  976.     for (j = 0; j < 32; ++j)
  977.       rowBuf[i][j] = NULL;
  978. }
  979.  
  980. DCTStream::~DCTStream() {
  981.   int i, j;
  982.  
  983.   delete str;
  984.   for (i = 0; i < numComps; ++i)
  985.     for (j = 0; j < mcuHeight; ++j)
  986.       gfree(rowBuf[i][j]);
  987. }
  988.  
  989. void DCTStream::reset() {
  990.   str->reset();
  991.   if (!readHeader()) {
  992.     y = height;
  993.     return;
  994.   }
  995.   restartMarker = 0xd0;
  996.   restart();
  997. }
  998.  
  999. int DCTStream::getChar() {
  1000.   int c;
  1001.  
  1002.   if (y >= height)
  1003.     return EOF;
  1004.   if (dy >= mcuHeight) {
  1005.     if (!readMCURow()) {
  1006.       y = height;
  1007.       return EOF;
  1008.     }
  1009.     comp = 0;
  1010.     x = 0;
  1011.     dy = 0;
  1012.   }
  1013.   c = rowBuf[comp][dy][x];
  1014.   if (++comp == numComps) {
  1015.     comp = 0;
  1016.     if (++x == width) {
  1017.       x = 0;
  1018.       ++y;
  1019.       ++dy;
  1020.     }
  1021.   }
  1022.   if (y == height)
  1023.     readTrailer();
  1024.   return c;
  1025. }
  1026.  
  1027. void DCTStream::restart() {
  1028.   int i;
  1029.  
  1030.   inputBits = 0;
  1031.   restartCtr = restartInterval;
  1032.   for (i = 0; i < numComps; ++i)
  1033.     compInfo[i].prevDC = 0;
  1034. }
  1035.  
  1036. GBool DCTStream::readMCURow() {
  1037.   Guchar data[64];
  1038.   double pY, pCb, pCr, pR, pG, pB;
  1039.   int h, v, horiz, vert, hSub, vSub;
  1040.   int x1, x2, y2, x3, y3, x4, y4, x5, y5, comp, i;
  1041.   int c;
  1042.  
  1043.   for (x1 = 0; x1 < width; x1 += mcuWidth) {
  1044.  
  1045.     // deal with restart marker
  1046.     if (restartInterval > 0 && restartCtr == 0) {
  1047.       c = readMarker();
  1048.       if (c != restartMarker) {
  1049.     error(getPos(), "Bad DCT data: incorrect restart marker");
  1050.     return gFalse;
  1051.       }
  1052.       if (++restartMarker == 0xd8)
  1053.     restartMarker = 0xd0;
  1054.       restart();
  1055.     }
  1056.  
  1057.     // read one MCU
  1058.     for (comp = 0; comp < numComps; ++comp) {
  1059.       h = compInfo[comp].hSample;
  1060.       v = compInfo[comp].vSample;
  1061.       horiz = mcuWidth / h;
  1062.       vert = mcuHeight / v;
  1063.       hSub = horiz / 8;
  1064.       vSub = vert / 8;
  1065.       for (y2 = 0; y2 < mcuHeight; y2 += vert) {
  1066.     for (x2 = 0; x2 < mcuWidth; x2 += horiz) {
  1067.       if (!readDataUnit(&dcHuffTables[compInfo[comp].dcHuffTable],
  1068.                 &acHuffTables[compInfo[comp].acHuffTable],
  1069.                 quantTables[compInfo[comp].quantTable],
  1070.                 &compInfo[comp].prevDC,
  1071.                 data))
  1072.         return gFalse;
  1073.       if (hSub == 1 && vSub == 1) {
  1074.         i = 0;
  1075.         for (y3 = 0; y3 < 8; ++y3)
  1076.           for (x3 = 0; x3 < 8; ++x3)
  1077.         rowBuf[comp][y2+y3][x1+x2+x3] = data[i++];
  1078.       } else {
  1079.         i = 0;
  1080.         for (y3 = 0, y4 = 0; y3 < 8; ++y3, y4 += vSub) {
  1081.           for (x3 = 0, x4 = 0; x3 < 8; ++x3, x4 += hSub) {
  1082.         for (y5 = 0; y5 < vSub; ++y5)
  1083.           for (x5 = 0; x5 < hSub; ++x5)
  1084.             rowBuf[comp][y2+y4+y5][x1+x2+x4+x5] = data[i];
  1085.         ++i;
  1086.           }
  1087.         }
  1088.       }
  1089.     }
  1090.       }
  1091.     }
  1092.     --restartCtr;
  1093.  
  1094.     // convert YCbCr to RGB
  1095.     if (colorXform && (numComps == 3 || numComps == 4)) {
  1096.       for (y2 = 0; y2 < mcuHeight; ++y2) {
  1097.     for (x2 = 0; x2 < mcuWidth; ++x2) {
  1098.       pY = rowBuf[0][y2][x1+x2];
  1099.       pCb = rowBuf[1][y2][x1+x2] - 128;
  1100.       pCr = rowBuf[2][y2][x1+x2] - 128;
  1101.       pR = pY + dctCrToR * pCr;
  1102.       if (pR < 0)
  1103.         pR = 0;
  1104.       else if (pR > 255)
  1105.         pR = 255;
  1106.       pG = pY + dctCbToG * pCb + dctCrToG * pCr;
  1107.       if (pG < 0)
  1108.         pG = 0;
  1109.       else if (pG > 255)
  1110.         pG = 255;
  1111.       pB = pY + dctCbToB * pCb;
  1112.       if (pB < 0)
  1113.         pB = 0;
  1114.       else if (pB > 255)
  1115.         pB = 255;
  1116.       rowBuf[0][y2][x1+x2] = (Guchar)(pR + 0.5);
  1117.       rowBuf[1][y2][x1+x2] = (Guchar)(pG + 0.5);
  1118.       rowBuf[2][y2][x1+x2] = (Guchar)(pB + 0.5);
  1119.     }
  1120.       }
  1121.     }
  1122.   }
  1123.   return gTrue;
  1124. }
  1125.  
  1126. // This IDCT algorithm is taken from:
  1127. //   Christoph Loeffler, Adriaan Ligtenberg, George S. Moschytz,
  1128. //   "Practical Fast 1-D DCT Algorithms with 11 Multiplications",
  1129. //   IEEE Intl. Conf. on Acoustics, Speech & Signal Processing, 1989,
  1130. //   988-991.
  1131. // The stage numbers mentioned in the comments refer to Figure 1 in this
  1132. // paper.
  1133. GBool DCTStream::readDataUnit(DCTHuffTable *dcHuffTable,
  1134.                   DCTHuffTable *acHuffTable,
  1135.                   Guchar quantTable[64], int *prevDC,
  1136.                   Guchar data[64]) {
  1137.   double tmp1[64];
  1138.   double v0, v1, v2, v3, v4, v5, v6, v7, t;
  1139.   int run, size, amp;
  1140.   int c;
  1141.   int i, j;
  1142.  
  1143.   // Huffman decode and dequantize
  1144.   size = readHuffSym(dcHuffTable);
  1145.   if (size == 9999)
  1146.     return gFalse;
  1147.   if (size > 0) {
  1148.     amp = readAmp(size);
  1149.     if (amp == 9999)
  1150.       return gFalse;
  1151.   } else {
  1152.     amp = 0;
  1153.   }
  1154.   tmp1[0] = (*prevDC += amp) * quantTable[0];
  1155.   for (i = 1; i < 64; ++i)
  1156.     tmp1[i] = 0;
  1157.   i = 1;
  1158.   while (i < 64) {
  1159.     run = 0;
  1160.     while ((c = readHuffSym(acHuffTable)) == 0xf0 && run < 0x30)
  1161.       run += 0x10;
  1162.     if (c == 9999)
  1163.       return gFalse;
  1164.     if (c == 0x00) {
  1165.       break;
  1166.     } else {
  1167.       run += (c >> 4) & 0x0f;
  1168.       size = c & 0x0f;
  1169.       amp = readAmp(size);
  1170.       if (amp == 9999)
  1171.     return gFalse;
  1172.       i += run;
  1173.       j = dctZigZag[i++];
  1174.       tmp1[j] = amp * quantTable[j];
  1175.     }
  1176.   }
  1177.  
  1178.   // inverse DCT on rows
  1179.   for (i = 0; i < 64; i += 8) {
  1180.  
  1181.     // stage 4
  1182.     v0 = dctSqrt2 * tmp1[i+0];
  1183.     v1 = dctSqrt2 * tmp1[i+4];
  1184.     v2 = tmp1[i+2];
  1185.     v3 = tmp1[i+6];
  1186.     v4 = dctSqrt1d2 * (tmp1[i+1] - tmp1[i+7]);
  1187.     v7 = dctSqrt1d2 * (tmp1[i+1] + tmp1[i+7]);
  1188.     v5 = tmp1[i+3];
  1189.     v6 = tmp1[i+5];
  1190.  
  1191.     /* stage 3 */
  1192.     t = 0.5 * (v0 - v1);
  1193.     v0 = 0.5 * (v0 + v1);
  1194.     v1 = t;
  1195.     t = v2 * dctSin6 + v3 * dctCos6;
  1196.     v2 = v2 * dctCos6 - v3 * dctSin6;
  1197.     v3 = t;
  1198.     t = 0.5 * (v4 - v6);
  1199.     v4 = 0.5 * (v4 + v6);
  1200.     v6 = t;
  1201.     t = 0.5 * (v7 + v5);
  1202.     v5 = 0.5 * (v7 - v5);
  1203.     v7 = t;
  1204.  
  1205.     /* stage 2 */
  1206.     t = 0.5 * (v0 - v3);
  1207.     v0 = 0.5 * (v0 + v3);
  1208.     v3 = t;
  1209.     t = 0.5 * (v1 - v2);
  1210.     v1 = 0.5 * (v1 + v2);
  1211.     v2 = t;
  1212.     t = v4 * dctSin3 + v7 * dctCos3;
  1213.     v4 = v4 * dctCos3 - v7 * dctSin3;
  1214.     v7 = t;
  1215.     t = v5 * dctSin1 + v6 * dctCos1;
  1216.     v5 = v5 * dctCos1 - v6 * dctSin1;
  1217.     v6 = t;
  1218.  
  1219.     /* stage 1 */
  1220.     tmp1[i+0] = v0 + v7;
  1221.     tmp1[i+7] = v0 - v7;
  1222.     tmp1[i+1] = v1 + v6;
  1223.     tmp1[i+6] = v1 - v6;
  1224.     tmp1[i+2] = v2 + v5;
  1225.     tmp1[i+5] = v2 - v5;
  1226.     tmp1[i+3] = v3 + v4;
  1227.     tmp1[i+4] = v3 - v4;
  1228.   }
  1229.  
  1230.   // inverse DCT on columns
  1231.   for (i = 0; i < 8; ++i) {
  1232.  
  1233.     // stage 4
  1234.     v0 = dctSqrt2 * tmp1[0*8+i];
  1235.     v1 = dctSqrt2 * tmp1[4*8+i];
  1236.     v2 = tmp1[2*8+i];
  1237.     v3 = tmp1[6*8+i];
  1238.     v4 = dctSqrt1d2 * (tmp1[1*8+i] - tmp1[7*8+i]);
  1239.     v7 = dctSqrt1d2 * (tmp1[1*8+i] + tmp1[7*8+i]);
  1240.     v5 = tmp1[3*8+i];
  1241.     v6 = tmp1[5*8+i];
  1242.  
  1243.     /* stage 3 */
  1244.     t = 0.5 * (v0 - v1);
  1245.     v0 = 0.5 * (v0 + v1);
  1246.     v1 = t;
  1247.     t = v2 * dctSin6 + v3 * dctCos6;
  1248.     v2 = v2 * dctCos6 - v3 * dctSin6;
  1249.     v3 = t;
  1250.     t = 0.5 * (v4 - v6);
  1251.     v4 = 0.5 * (v4 + v6);
  1252.     v6 = t;
  1253.     t = 0.5 * (v7 + v5);
  1254.     v5 = 0.5 * (v7 - v5);
  1255.     v7 = t;
  1256.  
  1257.     /* stage 2 */
  1258.     t = 0.5 * (v0 - v3);
  1259.     v0 = 0.5 * (v0 + v3);
  1260.     v3 = t;
  1261.     t = 0.5 * (v1 - v2);
  1262.     v1 = 0.5 * (v1 + v2);
  1263.     v2 = t;
  1264.     t = v4 * dctSin3 + v7 * dctCos3;
  1265.     v4 = v4 * dctCos3 - v7 * dctSin3;
  1266.     v7 = t;
  1267.     t = v5 * dctSin1 + v6 * dctCos1;
  1268.     v5 = v5 * dctCos1 - v6 * dctSin1;
  1269.     v6 = t;
  1270.  
  1271.     /* stage 1 */
  1272.     tmp1[0*8+i] = v0 + v7;
  1273.     tmp1[7*8+i] = v0 - v7;
  1274.     tmp1[1*8+i] = v1 + v6;
  1275.     tmp1[6*8+i] = v1 - v6;
  1276.     tmp1[2*8+i] = v2 + v5;
  1277.     tmp1[5*8+i] = v2 - v5;
  1278.     tmp1[3*8+i] = v3 + v4;
  1279.     tmp1[4*8+i] = v3 - v4;
  1280.   }
  1281.  
  1282.   // convert to 8-bit integers
  1283.   for (i = 0; i < 64; ++i) {
  1284.     if (tmp1[i] > 127)
  1285.       data[i] = 255;
  1286.     else if (tmp1[i] < -128)
  1287.       data[i] = 0;
  1288.     else
  1289.       data[i] = (Guchar)(tmp1[i] + 128.5);
  1290.   }
  1291.  
  1292.   return gTrue;
  1293. }
  1294.  
  1295. int DCTStream::readHuffSym(DCTHuffTable *table) {
  1296.   Gushort code;
  1297.   int bit;
  1298.   int codeBits;
  1299.  
  1300.   code = 0;
  1301.   codeBits = 0;
  1302.   do {
  1303.     // add a bit to the code
  1304.     if ((bit = readBit()) == EOF)
  1305.       return 9999;
  1306.     code = (code << 1) + bit;
  1307.     ++codeBits;
  1308.  
  1309.     // look up code
  1310.     if (code - table->firstCode[codeBits] < table->numCodes[codeBits]) {
  1311.       code -= table->firstCode[codeBits];
  1312.       return table->sym[table->firstSym[codeBits] + code];
  1313.     }
  1314.   } while (codeBits < 16);
  1315.  
  1316.   error(getPos(), "Bad Huffman code in DCT stream");
  1317.   return 9999;
  1318. }
  1319.  
  1320. int DCTStream::readAmp(int size) {
  1321.   int amp, bit;
  1322.   int bits;
  1323.  
  1324.   amp = 0;
  1325.   for (bits = 0; bits < size; ++bits) {
  1326.     if ((bit = readBit()) == EOF)
  1327.       return 9999;
  1328.     amp = (amp << 1) + bit;
  1329.   }
  1330.   if (amp < (1 << (size - 1)))
  1331.     amp -= (1 << size) - 1;
  1332.   return amp;
  1333. }
  1334.  
  1335. int DCTStream::readBit() {
  1336.   int bit;
  1337.   int c, c2;
  1338.  
  1339.   if (inputBits == 0) {
  1340.     if ((c = str->getChar()) == EOF)
  1341.       return EOF;
  1342.     if (c == 0xff) {
  1343.       do {
  1344.     c2 = str->getChar();
  1345.       } while (c2 == 0xff);
  1346.       if (c2 != 0x00) {
  1347.     error(getPos(), "Bad DCT data: missing 00 after ff");
  1348.     return EOF;
  1349.       }
  1350.     }
  1351.     inputBuf = c;
  1352.     inputBits = 8;
  1353.   }
  1354.   bit = (inputBuf >> (inputBits - 1)) & 1;
  1355.   --inputBits;
  1356.   return bit;
  1357. }
  1358.  
  1359. GBool DCTStream::readHeader() {
  1360.   GBool doScan;
  1361.   int minHSample, minVSample;
  1362.   int bufWidth;
  1363.   int c = 0;
  1364.   int i, j;
  1365.  
  1366.   width = height = 0;
  1367.   numComps = 0;
  1368.   numQuantTables = 0;
  1369.   numDCHuffTables = 0;
  1370.   numACHuffTables = 0;
  1371.   colorXform = 0;
  1372.   restartInterval = 0;
  1373.  
  1374.   // read headers
  1375.   doScan = gFalse;
  1376.   while (!doScan) {
  1377.     c = readMarker();
  1378.     switch (c) {
  1379.     case 0xc0:            // SOF0
  1380.       if (!readFrameInfo())
  1381.     return gFalse;
  1382.       break;
  1383.     case 0xc4:            // DHT
  1384.       if (!readHuffmanTables())
  1385.     return gFalse;
  1386.       break;
  1387.     case 0xd8:            // SOI
  1388.       break;
  1389.     case 0xda:            // SOS
  1390.       if (!readScanInfo())
  1391.     return gFalse;
  1392.       doScan = gTrue;
  1393.       break;
  1394.     case 0xdb:            // DQT
  1395.       if (!readQuantTables())
  1396.     return gFalse;
  1397.       break;
  1398.     case 0xdd:            // DRI
  1399.       if (!readRestartInterval())
  1400.     return gFalse;
  1401.       break;
  1402.     case 0xee:            // APP14
  1403.       if (!readAdobeMarker())
  1404.     return gFalse;
  1405.       break;
  1406.     case EOF:
  1407.       error(getPos(), "Bad DCT header");
  1408.       return gFalse;
  1409.     default:
  1410.       error(getPos(), "Unknown DCT marker <%02x>", c);
  1411.       return gFalse;
  1412.     }
  1413.   }
  1414.  
  1415.   // compute MCU size
  1416.   mcuWidth = minHSample = compInfo[0].hSample;
  1417.   mcuHeight = minVSample = compInfo[0].vSample;
  1418.   for (i = 1; i < numComps; ++i) {
  1419.     if (compInfo[i].hSample < minHSample)
  1420.       minHSample = compInfo[i].hSample;
  1421.     if (compInfo[i].vSample < minVSample)
  1422.       minVSample = compInfo[i].vSample;
  1423.     if (compInfo[i].hSample > mcuWidth)
  1424.       mcuWidth = compInfo[i].hSample;
  1425.     if (compInfo[i].vSample > mcuHeight)
  1426.       mcuHeight = compInfo[i].vSample;
  1427.   }
  1428.   for (i = 0; i < numComps; ++i) {
  1429.     compInfo[i].hSample /= minHSample;
  1430.     compInfo[i].vSample /= minVSample;
  1431.   }
  1432.   mcuWidth = (mcuWidth / minHSample) * 8;
  1433.   mcuHeight = (mcuHeight / minVSample) * 8;
  1434.  
  1435.   // allocate buffers
  1436.   bufWidth = ((width + mcuWidth - 1) / mcuWidth) * mcuWidth;
  1437.   for (i = 0; i < numComps; ++i)
  1438.     for (j = 0; j < mcuHeight; ++j)
  1439.       rowBuf[i][j] = (Guchar *)gmalloc(bufWidth * sizeof(Guchar));
  1440.  
  1441.   // initialize counters
  1442.   comp = 0;
  1443.   x = 0;
  1444.   y = 0;
  1445.   dy = mcuHeight;
  1446.  
  1447.   return gTrue;
  1448. }
  1449.  
  1450. GBool DCTStream::readFrameInfo() {
  1451.   int length;
  1452.   int prec;
  1453.   int i;
  1454.   int c;
  1455.  
  1456.   length = read16() - 2;
  1457.   prec = str->getChar();
  1458.   height = read16();
  1459.   width = read16();
  1460.   numComps = str->getChar();
  1461.   length -= 6;
  1462.   if (prec != 8) {
  1463.     error(getPos(), "Bad DCT precision %d", prec);
  1464.     return gFalse;
  1465.   }
  1466.   for (i = 0; i < numComps; ++i) {
  1467.     compInfo[i].id = str->getChar();
  1468.     compInfo[i].inScan = gFalse;
  1469.     c = str->getChar();
  1470.     compInfo[i].hSample = (c >> 4) & 0x0f;
  1471.     compInfo[i].vSample = c & 0x0f;
  1472.     compInfo[i].quantTable = str->getChar();
  1473.     compInfo[i].dcHuffTable = 0;
  1474.     compInfo[i].acHuffTable = 0;
  1475.   }
  1476.   return gTrue;
  1477. }
  1478.  
  1479. GBool DCTStream::readScanInfo() {
  1480.   int length;
  1481.   int scanComps, id, c;
  1482.   int i, j;
  1483.  
  1484.   length = read16() - 2;
  1485.   scanComps = str->getChar();
  1486.   --length;
  1487.   if (length != 2 * scanComps + 3) {
  1488.     error(getPos(), "Bad DCT scan info block");
  1489.     return gFalse;
  1490.   }
  1491.   for (i = 0; i < scanComps; ++i) {
  1492.     id = str->getChar();
  1493.     for (j = 0; j < numComps; ++j) {
  1494.       if (id == compInfo[j].id)
  1495.     break;
  1496.     }
  1497.     if (j == numComps) {
  1498.       error(getPos(), "Bad DCT component ID in scan info block");
  1499.       return gFalse;
  1500.     }
  1501.     compInfo[j].inScan = gTrue;
  1502.     c = str->getChar();
  1503.     compInfo[j].dcHuffTable = (c >> 4) & 0x0f;
  1504.     compInfo[j].acHuffTable = c & 0x0f;
  1505.   }
  1506.   str->getChar();
  1507.   str->getChar();
  1508.   str->getChar();
  1509.   return gTrue;
  1510. }
  1511.  
  1512. GBool DCTStream::readQuantTables() {
  1513.   int length;
  1514.   int i;
  1515.   int index;
  1516.  
  1517.   length = read16() - 2;
  1518.   while (length > 0) {
  1519.     index = str->getChar();
  1520.     if ((index & 0xf0) || index >= 4) {
  1521.       error(getPos(), "Bad DCT quantization table");
  1522.       return gFalse;
  1523.     }
  1524.     if (index == numQuantTables)
  1525.       numQuantTables = index + 1;
  1526.     for (i = 0; i < 64; ++i)
  1527.       quantTables[index][dctZigZag[i]] = str->getChar();
  1528.     length -= 65;
  1529.   }
  1530.   return gTrue;
  1531. }
  1532.  
  1533. GBool DCTStream::readHuffmanTables() {
  1534.   DCTHuffTable *tbl;
  1535.   int length;
  1536.   int index;
  1537.   Gushort code;
  1538.   Guchar sym;
  1539.   int i, j;
  1540.   int c;
  1541.  
  1542.   length = read16() - 2;
  1543.   while (length > 0) {
  1544.     index = str->getChar();
  1545.     --length;
  1546.     if ((index & 0x0f) >= 4) {
  1547.       error(getPos(), "Bad DCT Huffman table");
  1548.       return gFalse;
  1549.     }
  1550.     if (index & 0x10) {
  1551.       index &= 0x0f;
  1552.       if (index >= numACHuffTables)
  1553.     numACHuffTables = index+1;
  1554.       tbl = &acHuffTables[index];
  1555.     } else {
  1556.       if (index >= numDCHuffTables)
  1557.     numDCHuffTables = index+1;
  1558.       tbl = &dcHuffTables[index];
  1559.     }
  1560.     sym = 0;
  1561.     code = 0;
  1562.     for (i = 1; i <= 16; ++i) {
  1563.       c = str->getChar();
  1564.       tbl->firstSym[i] = sym;
  1565.       tbl->firstCode[i] = code;
  1566.       tbl->numCodes[i] = c;
  1567.       sym += c;
  1568.       code = (code + c) << 1;
  1569.     }
  1570.     length -= 16;
  1571.     j = 0;
  1572.     for (i = 0; i < sym; ++i)
  1573.       tbl->sym[i] = str->getChar();
  1574.     length -= sym;
  1575.   }
  1576.   return gTrue;
  1577. }
  1578.  
  1579. GBool DCTStream::readRestartInterval() {
  1580.   int length;
  1581.  
  1582.   length = read16();
  1583.   if (length != 4) {
  1584.     error(getPos(), "Bad DCT restart interval");
  1585.     return gFalse;
  1586.   }
  1587.   restartInterval = read16();
  1588.   return gTrue;
  1589. }
  1590.  
  1591. GBool DCTStream::readAdobeMarker() {
  1592.   int length, i;
  1593.   char buf[12];
  1594.   int c;
  1595.  
  1596.   length = read16();
  1597.   if (length != 14)
  1598.     goto err;
  1599.   for (i = 0; i < 12; ++i) {
  1600.     if ((c = str->getChar()) == EOF)
  1601.       goto err;
  1602.     buf[i] = c;
  1603.   }
  1604.   if (strncmp(buf, "Adobe", 5))
  1605.     goto err;
  1606.   colorXform = buf[11];
  1607.   return gTrue;
  1608.  
  1609.  err:
  1610.   error(getPos(), "Bad DCT Adobe APP14 marker");
  1611.   return gFalse;
  1612. }
  1613.  
  1614. GBool DCTStream::readTrailer() {
  1615.   int c;
  1616.  
  1617.   c = readMarker();
  1618.   if (c != 0xd9) {        // EOI
  1619.     error(getPos(), "Bad DCT trailer");
  1620.     return gFalse;
  1621.   }
  1622.   return gTrue;
  1623. }
  1624.  
  1625. int DCTStream::readMarker() {
  1626.   int c;
  1627.  
  1628.   do {
  1629.     do {
  1630.       c = str->getChar();
  1631.     } while (c != 0xff);
  1632.     do {
  1633.       c = str->getChar();
  1634.     } while (c == 0xff);
  1635.   } while (c == 0x00);
  1636.   return c;
  1637. }
  1638.  
  1639. int DCTStream::read16() {
  1640.   int c1, c2;
  1641.  
  1642.   if ((c1 = str->getChar()) == EOF)
  1643.     return EOF;
  1644.   if ((c2 = str->getChar()) == EOF)
  1645.     return EOF;
  1646.   return (c1 << 8) + c2;
  1647. }
  1648.  
  1649. GString *DCTStream::getPSFilter(char *indent) {
  1650.   GString *s;
  1651.  
  1652.   s = str->getPSFilter(indent);
  1653.   s->append(indent)->append("<< >> /DCTDecode filter\n");
  1654.   return s;
  1655. }
  1656.  
  1657. GBool DCTStream::isBinary(GBool last) {
  1658.   return str->isBinary(gTrue);
  1659. }
  1660.