📄 stream.cc
字号:
}GBool LZWStream::isBinary(GBool last) { return str->isBinary(gTrue);}//------------------------------------------------------------------------// RunLengthStream//------------------------------------------------------------------------RunLengthStream::RunLengthStream(Stream *strA): FilterStream(strA) { bufPtr = bufEnd = buf; eof = gFalse;}RunLengthStream::~RunLengthStream() { delete str;}void RunLengthStream::reset() { str->reset(); bufPtr = bufEnd = buf; eof = gFalse;}GString *RunLengthStream::getPSFilter(int psLevel, char *indent) { GString *s; if (psLevel < 2) { return NULL; } if (!(s = str->getPSFilter(psLevel, indent))) { return NULL; } s->append(indent)->append("/RunLengthDecode filter\n"); return s;}GBool RunLengthStream::isBinary(GBool last) { return str->isBinary(gTrue);}GBool RunLengthStream::fillBuf() { int c; int n, i; if (eof) return gFalse; c = str->getChar(); if (c == 0x80 || c == EOF) { eof = gTrue; return gFalse; } if (c < 0x80) { n = c + 1; for (i = 0; i < n; ++i) buf[i] = (char)str->getChar(); } else { n = 0x101 - c; c = str->getChar(); for (i = 0; i < n; ++i) buf[i] = (char)c; } bufPtr = buf; bufEnd = buf + n; return gTrue;}//------------------------------------------------------------------------// CCITTFaxStream//------------------------------------------------------------------------CCITTFaxStream::CCITTFaxStream(Stream *strA, int encodingA, GBool endOfLineA, GBool byteAlignA, int columnsA, int rowsA, GBool endOfBlockA, GBool blackA): FilterStream(strA) { encoding = encodingA; endOfLine = endOfLineA; byteAlign = byteAlignA; columns = columnsA; if (columns < 1) { columns = 1; } if (columns + 4 <= 0) { columns = INT_MAX - 4; } rows = rowsA; endOfBlock = endOfBlockA; black = blackA; refLine = (short *)gmallocn(columns + 3, sizeof(short)); codingLine = (short *)gmallocn(columns + 2, sizeof(short)); eof = gFalse; row = 0; nextLine2D = encoding < 0; inputBits = 0; codingLine[0] = 0; codingLine[1] = refLine[2] = columns; a0 = 1; buf = EOF;}CCITTFaxStream::~CCITTFaxStream() { delete str; gfree(refLine); gfree(codingLine);}void CCITTFaxStream::reset() { short code1; str->reset(); eof = gFalse; row = 0; nextLine2D = encoding < 0; inputBits = 0; codingLine[0] = 0; codingLine[1] = columns; a0 = 1; buf = EOF; // skip any initial zero bits and end-of-line marker, and get the 2D // encoding tag while ((code1 = lookBits(12)) == 0) { eatBits(1); } if (code1 == 0x001) { eatBits(12); } if (encoding > 0) { nextLine2D = !lookBits(1); eatBits(1); }}int CCITTFaxStream::lookChar() { short code1, code2, code3; int a0New; GBool err, gotEOL; int ret; int bits, i; // if at eof just return EOF if (eof && codingLine[a0] >= columns) { return EOF; } // read the next row err = gFalse; if (codingLine[a0] >= columns) { // 2-D encoding if (nextLine2D) { // state: // a0New = current position in coding line (0 <= a0New <= columns) // codingLine[a0] = last change in coding line // (black-to-white if a0 is even, // white-to-black if a0 is odd) // refLine[b1] = next change in reference line of opposite color // to a0 // invariants: // 0 <= codingLine[a0] <= a0New // <= refLine[b1] <= refLine[b1+1] <= columns // 0 <= a0 <= columns+1 // refLine[0] = 0 // refLine[n] = refLine[n+1] = columns // -- for some 1 <= n <= columns+1 // end condition: // 0 = codingLine[0] <= codingLine[1] < codingLine[2] < ... // < codingLine[n-1] < codingLine[n] = columns // -- where 1 <= n <= columns+1 for (i = 0; codingLine[i] < columns; ++i) { refLine[i] = codingLine[i]; } refLine[i] = refLine[i + 1] = columns; b1 = 1; a0New = codingLine[a0 = 0] = 0; do { code1 = getTwoDimCode(); switch (code1) { case twoDimPass: if (refLine[b1] < columns) { a0New = refLine[b1 + 1]; b1 += 2; } break; case twoDimHoriz: if ((a0 & 1) == 0) { code1 = code2 = 0; do { code1 += code3 = getWhiteCode(); } while (code3 >= 64); do { code2 += code3 = getBlackCode(); } while (code3 >= 64); } else { code1 = code2 = 0; do { code1 += code3 = getBlackCode(); } while (code3 >= 64); do { code2 += code3 = getWhiteCode(); } while (code3 >= 64); } if (code1 > 0 || code2 > 0) { if (a0New + code1 <= columns) { codingLine[a0 + 1] = a0New + code1; } else { codingLine[a0 + 1] = columns; } ++a0; if (codingLine[a0] + code2 <= columns) { codingLine[a0 + 1] = codingLine[a0] + code2; } else { codingLine[a0 + 1] = columns; } ++a0; a0New = codingLine[a0]; while (refLine[b1] <= a0New && refLine[b1] < columns) { b1 += 2; } } break; case twoDimVert0: if (refLine[b1] < columns) { a0New = codingLine[++a0] = refLine[b1]; ++b1; while (refLine[b1] <= a0New && refLine[b1] < columns) { b1 += 2; } } else { a0New = codingLine[++a0] = columns; } break; case twoDimVertR1: if (refLine[b1] + 1 < columns) { a0New = codingLine[++a0] = refLine[b1] + 1; ++b1; while (refLine[b1] <= a0New && refLine[b1] < columns) { b1 += 2; } } else { a0New = codingLine[++a0] = columns; } break; case twoDimVertL1: if (refLine[b1] - 1 > a0New || (a0 == 0 && refLine[b1] == 1)) { a0New = codingLine[++a0] = refLine[b1] - 1; --b1; while (refLine[b1] <= a0New && refLine[b1] < columns) { b1 += 2; } } break; case twoDimVertR2: if (refLine[b1] + 2 < columns) { a0New = codingLine[++a0] = refLine[b1] + 2; ++b1; while (refLine[b1] <= a0New && refLine[b1] < columns) { b1 += 2; } } else { a0New = codingLine[++a0] = columns; } break; case twoDimVertL2: if (refLine[b1] - 2 > a0New || (a0 == 0 && refLine[b1] == 2)) { a0New = codingLine[++a0] = refLine[b1] - 2; --b1; while (refLine[b1] <= a0New && refLine[b1] < columns) { b1 += 2; } } break; case twoDimVertR3: if (refLine[b1] + 3 < columns) { a0New = codingLine[++a0] = refLine[b1] + 3; ++b1; while (refLine[b1] <= a0New && refLine[b1] < columns) { b1 += 2; } } else { a0New = codingLine[++a0] = columns; } break; case twoDimVertL3: if (refLine[b1] - 3 > a0New || (a0 == 0 && refLine[b1] == 3)) { a0New = codingLine[++a0] = refLine[b1] - 3; --b1; while (refLine[b1] <= a0New && refLine[b1] < columns) { b1 += 2; } } break; case EOF: eof = gTrue; codingLine[a0 = 0] = columns; return EOF; default: error(getPos(), "Bad 2D code %04x in CCITTFax stream", code1); err = gTrue; break; } } while (codingLine[a0] < columns); // 1-D encoding } else { codingLine[a0 = 0] = 0; while (1) { code1 = 0; do { code1 += code3 = getWhiteCode(); } while (code3 >= 64); codingLine[a0+1] = codingLine[a0] + code1; ++a0; if (codingLine[a0] >= columns) { break; } code2 = 0; do { code2 += code3 = getBlackCode(); } while (code3 >= 64); codingLine[a0+1] = codingLine[a0] + code2; ++a0; if (codingLine[a0] >= columns) { break; } } } if (codingLine[a0] != columns) { error(getPos(), "CCITTFax row is wrong length (%d)", codingLine[a0]); // force the row to be the correct length while (codingLine[a0] > columns) { --a0; } codingLine[++a0] = columns; err = gTrue; } // byte-align the row if (byteAlign) { inputBits &= ~7; } // check for end-of-line marker, skipping over any extra zero bits gotEOL = gFalse; if (!endOfBlock && row == rows - 1) { eof = gTrue; } else { code1 = lookBits(12); while (code1 == 0) { eatBits(1); code1 = lookBits(12); } if (code1 == 0x001) { eatBits(12); gotEOL = gTrue; } else if (code1 == EOF) { eof = gTrue; } } // get 2D encoding tag if (!eof && encoding > 0) { nextLine2D = !lookBits(1); eatBits(1); } // check for end-of-block marker if (endOfBlock && gotEOL) { code1 = lookBits(12); if (code1 == 0x001) { eatBits(12); if (encoding > 0) { lookBits(1); eatBits(1); } if (encoding >= 0) { for (i = 0; i < 4; ++i) { code1 = lookBits(12); if (code1 != 0x001) { error(getPos(), "Bad RTC code in CCITTFax stream"); } eatBits(12); if (encoding > 0) { lookBits(1); eatBits(1); } } } eof = gTrue; } // look for an end-of-line marker after an error -- we only do // this if we know the stream contains end-of-line markers because // the "just plow on" technique tends to work better otherwise } else if (err && endOfLine) { do { if (code1 == EOF) { eof = gTrue; return EOF; } eatBits(1); code1 = lookBits(13); } while ((code1 >> 1) != 0x001); eatBits(12); if (encoding > 0) { eatBits(1); nextLine2D = !(code1 & 1); } } a0 = 0; outputBits = codingLine[1] - codingLine[0]; if (outputBits == 0) { a0 = 1; outputBits = codingLine[2] - codingLine[1]; } ++row; } // get a byte if (outputBits >= 8) { ret = ((a0 & 1) == 0) ? 0xff : 0x00; if ((outputBits -= 8) == 0) { ++a0; if (codingLine[a0] < columns) { outputBits = codingLine[a0 + 1] - codingLine[a0]; } } } else { bits = 8; ret = 0; do { if (outputBits > bits) { i = bits; bits = 0; if ((a0 & 1) == 0) { ret |= 0xff >> (8 - i); } outputBits -= i; } else { i = outputBits; bits -= outputBits; if ((a0 & 1) == 0) { ret |= (0xff >> (8 - i)) << bits; } outputBits = 0; ++a0; if (codingLine[a0] < columns) { outputBits = codingLine[a0 + 1] - codingLine[a0]; } } } while (bits > 0 && codingLine[a0] < columns); } buf = black ? (ret ^ 0xff) : ret; return buf;}short CCITTFaxStream::getTwoDimCode() { short code; CCITTCode *p; int n; code = 0; // make gcc happy if (endOfBlock) { code = lookBits(7); p = &twoDimTab1[code]; if (p->bits > 0) { eatBits(p->bits); return p->n; } } else { for (n = 1; n <= 7; ++n) { code = lookBits(n); if (n < 7) { code <<= 7 - n; } p = &twoDimTab1[code]; if (p->bits == n) { eatBits(n); return p->n; } } } error(getPos(), "Bad two dim code (%04x) in CCITTFax stream", code); return EOF;}short CCITTFaxStream::getWhiteCode() { short code; CCITTCode *p; int n; code = 0; // make gcc happy if (endOfBlock) { code = lookBits(12); if ((code >> 5) == 0) { p = &whiteTab1[code]; } else { p = &whiteTab2[code >> 3]; } if (p->bits > 0) { eatBits(p->bits); return p->n; } } else { for (n = 1; n <= 9; ++n) { code = lookBits(n); if (n < 9) { code <<= 9 - n; } p = &whiteTab2[code]; if (p->bits == n) { eatBits(n); return p->n; } } for (n = 11; n <= 12; ++n) { code = lookBits(n); if (n < 12) { code <<= 12 - n; } p = &whiteTab1[code]; if (p->bits == n) { eatBits(n); return p->n; } } } error(getPos(), "Bad white code (%04x) in CCITTFax stream", code); // eat a bit and return a positive number so that the caller doesn't // go into an infinite loop eatBits(1); return 1;}short CCITTFaxStream::getBlackCode() { short code; CCITTCode *p; int n; code = 0; // make gcc happy if (endOfBlock) { code = lookBits(13); if ((code >> 7) == 0) { p = &blackTab1[code]; } else if ((code >> 9) == 0) { p = &blackTab2[(code >> 1) - 64]; } else { p = &blackTab3[code >> 7]; } if (p->bits > 0) { eatBits(p->bits); return p->n; } } else { for (n = 2; n <= 6; ++n) { code = lookBits(n); if (n < 6) { code <<= 6 - n; } p = &blackTab3[code]; if (p->bits == n) { eatBits(n); return p->n; } } for (n = 7; n <= 12; ++n) { code = lookBits(n); if (n < 12) { code <<= 12 - n; } if (code >= 64) { p = &blackTab2[code - 64]; if (p->bits == n) { eatBits(n); return p->n; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -