Lines 438-449
void JBIG2HuffmanDecoder::buildTable(JBIG2HuffmanTable *table, Guint len) {
Link Here
|
438 |
table[i] = table[len]; |
438 |
table[i] = table[len]; |
439 |
|
439 |
|
440 |
// assign prefixes |
440 |
// assign prefixes |
441 |
i = 0; |
441 |
if (table[0].rangeLen != jbig2HuffmanEOT) { |
442 |
prefix = 0; |
442 |
i = 0; |
443 |
table[i++].prefix = prefix++; |
443 |
prefix = 0; |
444 |
for (; table[i].rangeLen != jbig2HuffmanEOT; ++i) { |
444 |
table[i++].prefix = prefix++; |
445 |
prefix <<= table[i].prefixLen - table[i-1].prefixLen; |
445 |
for (; table[i].rangeLen != jbig2HuffmanEOT; ++i) { |
446 |
table[i].prefix = prefix++; |
446 |
prefix <<= table[i].prefixLen - table[i-1].prefixLen; |
|
|
447 |
table[i].prefix = prefix++; |
448 |
} |
447 |
} |
449 |
} |
448 |
} |
450 |
} |
449 |
|
451 |
|
Lines 507-513
int JBIG2MMRDecoder::get2DCode() {
Link Here
|
507 |
} |
509 |
} |
508 |
if (p->bits < 0) { |
510 |
if (p->bits < 0) { |
509 |
error(str->getPos(), "Bad two dim code in JBIG2 MMR stream"); |
511 |
error(str->getPos(), "Bad two dim code in JBIG2 MMR stream"); |
510 |
return 0; |
512 |
return EOF; |
511 |
} |
513 |
} |
512 |
bufLen -= p->bits; |
514 |
bufLen -= p->bits; |
513 |
return p->n; |
515 |
return p->n; |
Lines 779-784
void JBIG2Bitmap::clearToOne() {
Link Here
|
779 |
inline void JBIG2Bitmap::getPixelPtr(int x, int y, JBIG2BitmapPtr *ptr) { |
781 |
inline void JBIG2Bitmap::getPixelPtr(int x, int y, JBIG2BitmapPtr *ptr) { |
780 |
if (y < 0 || y >= h || x >= w) { |
782 |
if (y < 0 || y >= h || x >= w) { |
781 |
ptr->p = NULL; |
783 |
ptr->p = NULL; |
|
|
784 |
ptr->shift = 0; // make gcc happy |
785 |
ptr->x = 0; // make gcc happy |
782 |
} else if (x < 0) { |
786 |
} else if (x < 0) { |
783 |
ptr->p = &data[y * line]; |
787 |
ptr->p = &data[y * line]; |
784 |
ptr->shift = 7; |
788 |
ptr->shift = 7; |
Lines 823-828
void JBIG2Bitmap::combine(JBIG2Bitmap *bitmap, int x, int y,
Link Here
|
823 |
Guint src0, src1, src, dest, s1, s2, m1, m2, m3; |
827 |
Guint src0, src1, src, dest, s1, s2, m1, m2, m3; |
824 |
GBool oneByte; |
828 |
GBool oneByte; |
825 |
|
829 |
|
|
|
830 |
// check for the pathological case where y = -2^31 |
831 |
if (y < -0x7fffffff) { |
832 |
return; |
833 |
} |
826 |
if (y < 0) { |
834 |
if (y < 0) { |
827 |
y0 = -y; |
835 |
y0 = -y; |
828 |
} else { |
836 |
} else { |
Lines 1325-1330
void JBIG2Stream::readSegments() {
Link Here
|
1325 |
// keep track of the start of the segment data |
1333 |
// keep track of the start of the segment data |
1326 |
segDataPos = getPos(); |
1334 |
segDataPos = getPos(); |
1327 |
|
1335 |
|
|
|
1336 |
// check for missing page information segment |
1337 |
if (!pageBitmap && ((segType >= 4 && segType <= 7) || |
1338 |
(segType >= 20 && segType <= 43))) { |
1339 |
error(getPos(), "First JBIG2 segment associated with a page must be a page information segment"); |
1340 |
goto syntaxError; |
1341 |
} |
1342 |
|
1328 |
// read the segment data |
1343 |
// read the segment data |
1329 |
switch (segType) { |
1344 |
switch (segType) { |
1330 |
case 0: |
1345 |
case 0: |
Lines 1479-1484
GBool JBIG2Stream::readSymbolDictSeg(Guint segNum, Guint length,
Link Here
|
1479 |
Guint i, j, k; |
1494 |
Guint i, j, k; |
1480 |
Guchar *p; |
1495 |
Guchar *p; |
1481 |
|
1496 |
|
|
|
1497 |
symWidths = NULL; |
1498 |
|
1482 |
// symbol dictionary flags |
1499 |
// symbol dictionary flags |
1483 |
if (!readUWord(&flags)) { |
1500 |
if (!readUWord(&flags)) { |
1484 |
goto eofError; |
1501 |
goto eofError; |
Lines 1539-1545
GBool JBIG2Stream::readSymbolDictSeg(Guint segNum, Guint length,
Link Here
|
1539 |
// part of it |
1556 |
// part of it |
1540 |
if ((seg = findSegment(refSegs[i]))) { |
1557 |
if ((seg = findSegment(refSegs[i]))) { |
1541 |
if (seg->getType() == jbig2SegSymbolDict) { |
1558 |
if (seg->getType() == jbig2SegSymbolDict) { |
1542 |
numInputSyms += ((JBIG2SymbolDict *)seg)->getSize(); |
1559 |
j = ((JBIG2SymbolDict *)seg)->getSize(); |
|
|
1560 |
if (numInputSyms > UINT_MAX - j) { |
1561 |
error(getPos(), "Too many input symbols in JBIG2 symbol dictionary"); |
1562 |
delete codeTables; |
1563 |
goto eofError; |
1564 |
} |
1565 |
numInputSyms += j; |
1543 |
} else if (seg->getType() == jbig2SegCodeTable) { |
1566 |
} else if (seg->getType() == jbig2SegCodeTable) { |
1544 |
codeTables->append(seg); |
1567 |
codeTables->append(seg); |
1545 |
} |
1568 |
} |
Lines 1548-1560
GBool JBIG2Stream::readSymbolDictSeg(Guint segNum, Guint length,
Link Here
|
1548 |
return gFalse; |
1571 |
return gFalse; |
1549 |
} |
1572 |
} |
1550 |
} |
1573 |
} |
|
|
1574 |
if (numInputSyms > UINT_MAX - numNewSyms) { |
1575 |
error(getPos(), "Too many input symbols in JBIG2 symbol dictionary"); |
1576 |
delete codeTables; |
1577 |
goto eofError; |
1578 |
} |
1551 |
|
1579 |
|
1552 |
// compute symbol code length |
1580 |
// compute symbol code length |
1553 |
symCodeLen = 0; |
1581 |
symCodeLen = 1; |
1554 |
i = 1; |
1582 |
i = (numInputSyms + numNewSyms) >> 1; |
1555 |
while (i < numInputSyms + numNewSyms) { |
1583 |
while (i) { |
1556 |
++symCodeLen; |
1584 |
++symCodeLen; |
1557 |
i <<= 1; |
1585 |
i >>= 1; |
1558 |
} |
1586 |
} |
1559 |
|
1587 |
|
1560 |
// get the input symbol bitmaps |
1588 |
// get the input symbol bitmaps |
Lines 1585-1590
GBool JBIG2Stream::readSymbolDictSeg(Guint segNum, Guint length,
Link Here
|
1585 |
} else if (huffDH == 1) { |
1613 |
} else if (huffDH == 1) { |
1586 |
huffDHTable = huffTableE; |
1614 |
huffDHTable = huffTableE; |
1587 |
} else { |
1615 |
} else { |
|
|
1616 |
if (i >= (Guint)codeTables->getLength()) { |
1617 |
goto codeTableError; |
1618 |
} |
1588 |
huffDHTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable(); |
1619 |
huffDHTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable(); |
1589 |
} |
1620 |
} |
1590 |
if (huffDW == 0) { |
1621 |
if (huffDW == 0) { |
Lines 1592-1608
GBool JBIG2Stream::readSymbolDictSeg(Guint segNum, Guint length,
Link Here
|
1592 |
} else if (huffDW == 1) { |
1623 |
} else if (huffDW == 1) { |
1593 |
huffDWTable = huffTableC; |
1624 |
huffDWTable = huffTableC; |
1594 |
} else { |
1625 |
} else { |
|
|
1626 |
if (i >= (Guint)codeTables->getLength()) { |
1627 |
goto codeTableError; |
1628 |
} |
1595 |
huffDWTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable(); |
1629 |
huffDWTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable(); |
1596 |
} |
1630 |
} |
1597 |
if (huffBMSize == 0) { |
1631 |
if (huffBMSize == 0) { |
1598 |
huffBMSizeTable = huffTableA; |
1632 |
huffBMSizeTable = huffTableA; |
1599 |
} else { |
1633 |
} else { |
|
|
1634 |
if (i >= (Guint)codeTables->getLength()) { |
1635 |
goto codeTableError; |
1636 |
} |
1600 |
huffBMSizeTable = |
1637 |
huffBMSizeTable = |
1601 |
((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable(); |
1638 |
((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable(); |
1602 |
} |
1639 |
} |
1603 |
if (huffAggInst == 0) { |
1640 |
if (huffAggInst == 0) { |
1604 |
huffAggInstTable = huffTableA; |
1641 |
huffAggInstTable = huffTableA; |
1605 |
} else { |
1642 |
} else { |
|
|
1643 |
if (i >= (Guint)codeTables->getLength()) { |
1644 |
goto codeTableError; |
1645 |
} |
1606 |
huffAggInstTable = |
1646 |
huffAggInstTable = |
1607 |
((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable(); |
1647 |
((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable(); |
1608 |
} |
1648 |
} |
Lines 1635-1641
GBool JBIG2Stream::readSymbolDictSeg(Guint segNum, Guint length,
Link Here
|
1635 |
} |
1675 |
} |
1636 |
|
1676 |
|
1637 |
// allocate symbol widths storage |
1677 |
// allocate symbol widths storage |
1638 |
symWidths = NULL; |
|
|
1639 |
if (huff && !refAgg) { |
1678 |
if (huff && !refAgg) { |
1640 |
symWidths = (Guint *)gmallocn(numNewSyms, sizeof(Guint)); |
1679 |
symWidths = (Guint *)gmallocn(numNewSyms, sizeof(Guint)); |
1641 |
} |
1680 |
} |
Lines 1677-1682
GBool JBIG2Stream::readSymbolDictSeg(Guint segNum, Guint length,
Link Here
|
1677 |
goto syntaxError; |
1716 |
goto syntaxError; |
1678 |
} |
1717 |
} |
1679 |
symWidth += dw; |
1718 |
symWidth += dw; |
|
|
1719 |
if (i >= numNewSyms) { |
1720 |
error(getPos(), "Too many symbols in JBIG2 symbol dictionary"); |
1721 |
goto syntaxError; |
1722 |
} |
1680 |
|
1723 |
|
1681 |
// using a collective bitmap, so don't read a bitmap here |
1724 |
// using a collective bitmap, so don't read a bitmap here |
1682 |
if (huff && !refAgg) { |
1725 |
if (huff && !refAgg) { |
Lines 1713-1718
GBool JBIG2Stream::readSymbolDictSeg(Guint segNum, Guint length,
Link Here
|
1713 |
arithDecoder->decodeInt(&refDX, iardxStats); |
1756 |
arithDecoder->decodeInt(&refDX, iardxStats); |
1714 |
arithDecoder->decodeInt(&refDY, iardyStats); |
1757 |
arithDecoder->decodeInt(&refDY, iardyStats); |
1715 |
} |
1758 |
} |
|
|
1759 |
if (symID >= numInputSyms + i) { |
1760 |
error(getPos(), "Invalid symbol ID in JBIG2 symbol dictionary"); |
1761 |
goto syntaxError; |
1762 |
} |
1716 |
refBitmap = bitmaps[symID]; |
1763 |
refBitmap = bitmaps[symID]; |
1717 |
bitmaps[numInputSyms + i] = |
1764 |
bitmaps[numInputSyms + i] = |
1718 |
readGenericRefinementRegion(symWidth, symHeight, |
1765 |
readGenericRefinementRegion(symWidth, symHeight, |
Lines 1779-1784
GBool JBIG2Stream::readSymbolDictSeg(Guint segNum, Guint length,
Link Here
|
1779 |
} else { |
1826 |
} else { |
1780 |
arithDecoder->decodeInt(&run, iaexStats); |
1827 |
arithDecoder->decodeInt(&run, iaexStats); |
1781 |
} |
1828 |
} |
|
|
1829 |
if (i + run > numInputSyms + numNewSyms || |
1830 |
(ex && j + run > numExSyms)) { |
1831 |
error(getPos(), "Too many exported symbols in JBIG2 symbol dictionary"); |
1832 |
delete symbolDict; |
1833 |
goto syntaxError; |
1834 |
} |
1782 |
if (ex) { |
1835 |
if (ex) { |
1783 |
for (cnt = 0; cnt < run; ++cnt) { |
1836 |
for (cnt = 0; cnt < run; ++cnt) { |
1784 |
symbolDict->setBitmap(j++, bitmaps[i++]->copy()); |
1837 |
symbolDict->setBitmap(j++, bitmaps[i++]->copy()); |
Lines 1793-1798
GBool JBIG2Stream::readSymbolDictSeg(Guint segNum, Guint length,
Link Here
|
1793 |
// correctly like bug #19702 |
1846 |
// correctly like bug #19702 |
1794 |
symbolDict->setBitmap(j, NULL); |
1847 |
symbolDict->setBitmap(j, NULL); |
1795 |
} |
1848 |
} |
|
|
1849 |
if (j != numExSyms) { |
1850 |
error(getPos(), "Too few symbols in JBIG2 symbol dictionary"); |
1851 |
delete symbolDict; |
1852 |
goto syntaxError; |
1853 |
} |
1796 |
|
1854 |
|
1797 |
for (i = 0; i < numNewSyms; ++i) { |
1855 |
for (i = 0; i < numNewSyms; ++i) { |
1798 |
delete bitmaps[numInputSyms + i]; |
1856 |
delete bitmaps[numInputSyms + i]; |
Lines 1815-1820
GBool JBIG2Stream::readSymbolDictSeg(Guint segNum, Guint length,
Link Here
|
1815 |
|
1873 |
|
1816 |
return gTrue; |
1874 |
return gTrue; |
1817 |
|
1875 |
|
|
|
1876 |
codeTableError: |
1877 |
error(getPos(), "Missing code table in JBIG2 symbol dictionary"); |
1878 |
delete codeTables; |
1879 |
|
1818 |
syntaxError: |
1880 |
syntaxError: |
1819 |
for (i = 0; i < numNewSyms; ++i) { |
1881 |
for (i = 0; i < numNewSyms; ++i) { |
1820 |
if (bitmaps[numInputSyms + i]) { |
1882 |
if (bitmaps[numInputSyms + i]) { |
Lines 1917-1922
void JBIG2Stream::readTextRegionSeg(Guint segNum, GBool imm,
Link Here
|
1917 |
} |
1979 |
} |
1918 |
} else { |
1980 |
} else { |
1919 |
error(getPos(), "Invalid segment reference in JBIG2 text region"); |
1981 |
error(getPos(), "Invalid segment reference in JBIG2 text region"); |
|
|
1982 |
delete codeTables; |
1983 |
return; |
1920 |
} |
1984 |
} |
1921 |
} |
1985 |
} |
1922 |
symCodeLen = 0; |
1986 |
symCodeLen = 0; |
Lines 1951-1956
void JBIG2Stream::readTextRegionSeg(Guint segNum, GBool imm,
Link Here
|
1951 |
} else if (huffFS == 1) { |
2015 |
} else if (huffFS == 1) { |
1952 |
huffFSTable = huffTableG; |
2016 |
huffFSTable = huffTableG; |
1953 |
} else { |
2017 |
} else { |
|
|
2018 |
if (i >= (Guint)codeTables->getLength()) { |
2019 |
goto codeTableError; |
2020 |
} |
1954 |
huffFSTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable(); |
2021 |
huffFSTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable(); |
1955 |
} |
2022 |
} |
1956 |
if (huffDS == 0) { |
2023 |
if (huffDS == 0) { |
Lines 1960-1965
void JBIG2Stream::readTextRegionSeg(Guint segNum, GBool imm,
Link Here
|
1960 |
} else if (huffDS == 2) { |
2027 |
} else if (huffDS == 2) { |
1961 |
huffDSTable = huffTableJ; |
2028 |
huffDSTable = huffTableJ; |
1962 |
} else { |
2029 |
} else { |
|
|
2030 |
if (i >= (Guint)codeTables->getLength()) { |
2031 |
goto codeTableError; |
2032 |
} |
1963 |
huffDSTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable(); |
2033 |
huffDSTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable(); |
1964 |
} |
2034 |
} |
1965 |
if (huffDT == 0) { |
2035 |
if (huffDT == 0) { |
Lines 1969-1974
void JBIG2Stream::readTextRegionSeg(Guint segNum, GBool imm,
Link Here
|
1969 |
} else if (huffDT == 2) { |
2039 |
} else if (huffDT == 2) { |
1970 |
huffDTTable = huffTableM; |
2040 |
huffDTTable = huffTableM; |
1971 |
} else { |
2041 |
} else { |
|
|
2042 |
if (i >= (Guint)codeTables->getLength()) { |
2043 |
goto codeTableError; |
2044 |
} |
1972 |
huffDTTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable(); |
2045 |
huffDTTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable(); |
1973 |
} |
2046 |
} |
1974 |
if (huffRDW == 0) { |
2047 |
if (huffRDW == 0) { |
Lines 1976-1981
void JBIG2Stream::readTextRegionSeg(Guint segNum, GBool imm,
Link Here
|
1976 |
} else if (huffRDW == 1) { |
2049 |
} else if (huffRDW == 1) { |
1977 |
huffRDWTable = huffTableO; |
2050 |
huffRDWTable = huffTableO; |
1978 |
} else { |
2051 |
} else { |
|
|
2052 |
if (i >= (Guint)codeTables->getLength()) { |
2053 |
goto codeTableError; |
2054 |
} |
1979 |
huffRDWTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable(); |
2055 |
huffRDWTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable(); |
1980 |
} |
2056 |
} |
1981 |
if (huffRDH == 0) { |
2057 |
if (huffRDH == 0) { |
Lines 1983-1988
void JBIG2Stream::readTextRegionSeg(Guint segNum, GBool imm,
Link Here
|
1983 |
} else if (huffRDH == 1) { |
2059 |
} else if (huffRDH == 1) { |
1984 |
huffRDHTable = huffTableO; |
2060 |
huffRDHTable = huffTableO; |
1985 |
} else { |
2061 |
} else { |
|
|
2062 |
if (i >= (Guint)codeTables->getLength()) { |
2063 |
goto codeTableError; |
2064 |
} |
1986 |
huffRDHTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable(); |
2065 |
huffRDHTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable(); |
1987 |
} |
2066 |
} |
1988 |
if (huffRDX == 0) { |
2067 |
if (huffRDX == 0) { |
Lines 1990-1995
void JBIG2Stream::readTextRegionSeg(Guint segNum, GBool imm,
Link Here
|
1990 |
} else if (huffRDX == 1) { |
2069 |
} else if (huffRDX == 1) { |
1991 |
huffRDXTable = huffTableO; |
2070 |
huffRDXTable = huffTableO; |
1992 |
} else { |
2071 |
} else { |
|
|
2072 |
if (i >= (Guint)codeTables->getLength()) { |
2073 |
goto codeTableError; |
2074 |
} |
1993 |
huffRDXTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable(); |
2075 |
huffRDXTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable(); |
1994 |
} |
2076 |
} |
1995 |
if (huffRDY == 0) { |
2077 |
if (huffRDY == 0) { |
Lines 1997-2007
void JBIG2Stream::readTextRegionSeg(Guint segNum, GBool imm,
Link Here
|
1997 |
} else if (huffRDY == 1) { |
2079 |
} else if (huffRDY == 1) { |
1998 |
huffRDYTable = huffTableO; |
2080 |
huffRDYTable = huffTableO; |
1999 |
} else { |
2081 |
} else { |
|
|
2082 |
if (i >= (Guint)codeTables->getLength()) { |
2083 |
goto codeTableError; |
2084 |
} |
2000 |
huffRDYTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable(); |
2085 |
huffRDYTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable(); |
2001 |
} |
2086 |
} |
2002 |
if (huffRSize == 0) { |
2087 |
if (huffRSize == 0) { |
2003 |
huffRSizeTable = huffTableA; |
2088 |
huffRSizeTable = huffTableA; |
2004 |
} else { |
2089 |
} else { |
|
|
2090 |
if (i >= (Guint)codeTables->getLength()) { |
2091 |
goto codeTableError; |
2092 |
} |
2005 |
huffRSizeTable = |
2093 |
huffRSizeTable = |
2006 |
((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable(); |
2094 |
((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable(); |
2007 |
} |
2095 |
} |
Lines 2098-2105
void JBIG2Stream::readTextRegionSeg(Guint segNum, GBool imm,
Link Here
|
2098 |
|
2186 |
|
2099 |
return; |
2187 |
return; |
2100 |
|
2188 |
|
|
|
2189 |
codeTableError: |
2190 |
error(getPos(), "Missing code table in JBIG2 text region"); |
2191 |
gfree(codeTables); |
2192 |
delete syms; |
2193 |
return; |
2194 |
|
2101 |
eofError: |
2195 |
eofError: |
2102 |
error(getPos(), "Unexpected EOF in JBIG2 stream"); |
2196 |
error(getPos(), "Unexpected EOF in JBIG2 stream"); |
|
|
2197 |
return; |
2103 |
} |
2198 |
} |
2104 |
|
2199 |
|
2105 |
JBIG2Bitmap *JBIG2Stream::readTextRegion(GBool huff, GBool refine, |
2200 |
JBIG2Bitmap *JBIG2Stream::readTextRegion(GBool huff, GBool refine, |
Lines 2226-2232
JBIG2Bitmap *JBIG2Stream::readTextRegion(GBool huff, GBool refine,
Link Here
|
2226 |
decodeSuccess = decodeSuccess && arithDecoder->decodeInt(&rdy, iardyStats); |
2321 |
decodeSuccess = decodeSuccess && arithDecoder->decodeInt(&rdy, iardyStats); |
2227 |
} |
2322 |
} |
2228 |
|
2323 |
|
2229 |
if (decodeSuccess) |
2324 |
if (decodeSuccess && syms[symID]) |
2230 |
{ |
2325 |
{ |
2231 |
refDX = ((rdw >= 0) ? rdw : rdw - 1) / 2 + rdx; |
2326 |
refDX = ((rdw >= 0) ? rdw : rdw - 1) / 2 + rdx; |
2232 |
refDY = ((rdh >= 0) ? rdh : rdh - 1) / 2 + rdy; |
2327 |
refDY = ((rdh >= 0) ? rdh : rdh - 1) / 2 + rdy; |
Lines 2577-2583
void JBIG2Stream::readGenericRegionSeg(Guint segNum, GBool imm,
Link Here
|
2577 |
|
2672 |
|
2578 |
// read the bitmap |
2673 |
// read the bitmap |
2579 |
bitmap = readGenericBitmap(mmr, w, h, templ, tpgdOn, gFalse, |
2674 |
bitmap = readGenericBitmap(mmr, w, h, templ, tpgdOn, gFalse, |
2580 |
NULL, atx, aty, mmr ? 0 : length - 18); |
2675 |
NULL, atx, aty, mmr ? length - 18 : 0); |
2581 |
|
2676 |
|
2582 |
// combine the region bitmap into the page bitmap |
2677 |
// combine the region bitmap into the page bitmap |
2583 |
if (imm) { |
2678 |
if (imm) { |
Lines 2599-2604
void JBIG2Stream::readGenericRegionSeg(Guint segNum, GBool imm,
Link Here
|
2599 |
error(getPos(), "Unexpected EOF in JBIG2 stream"); |
2694 |
error(getPos(), "Unexpected EOF in JBIG2 stream"); |
2600 |
} |
2695 |
} |
2601 |
|
2696 |
|
|
|
2697 |
inline void JBIG2Stream::mmrAddPixels(int a1, int blackPixels, |
2698 |
int *codingLine, int *a0i, int w) { |
2699 |
if (a1 > codingLine[*a0i]) { |
2700 |
if (a1 > w) { |
2701 |
error(getPos(), "JBIG2 MMR row is wrong length ({0:d})", a1); |
2702 |
a1 = w; |
2703 |
} |
2704 |
if ((*a0i & 1) ^ blackPixels) { |
2705 |
++*a0i; |
2706 |
} |
2707 |
codingLine[*a0i] = a1; |
2708 |
} |
2709 |
} |
2710 |
|
2711 |
inline void JBIG2Stream::mmrAddPixelsNeg(int a1, int blackPixels, |
2712 |
int *codingLine, int *a0i, int w) { |
2713 |
if (a1 > codingLine[*a0i]) { |
2714 |
if (a1 > w) { |
2715 |
error(getPos(), "JBIG2 MMR row is wrong length ({0:d})", a1); |
2716 |
a1 = w; |
2717 |
} |
2718 |
if ((*a0i & 1) ^ blackPixels) { |
2719 |
++*a0i; |
2720 |
} |
2721 |
codingLine[*a0i] = a1; |
2722 |
} else if (a1 < codingLine[*a0i]) { |
2723 |
if (a1 < 0) { |
2724 |
error(getPos(), "Invalid JBIG2 MMR code"); |
2725 |
a1 = 0; |
2726 |
} |
2727 |
while (*a0i > 0 && a1 <= codingLine[*a0i - 1]) { |
2728 |
--*a0i; |
2729 |
} |
2730 |
codingLine[*a0i] = a1; |
2731 |
} |
2732 |
} |
2733 |
|
2602 |
JBIG2Bitmap *JBIG2Stream::readGenericBitmap(GBool mmr, int w, int h, |
2734 |
JBIG2Bitmap *JBIG2Stream::readGenericBitmap(GBool mmr, int w, int h, |
2603 |
int templ, GBool tpgdOn, |
2735 |
int templ, GBool tpgdOn, |
2604 |
GBool useSkip, JBIG2Bitmap *skip, |
2736 |
GBool useSkip, JBIG2Bitmap *skip, |
Lines 2611-2617
JBIG2Bitmap *JBIG2Stream::readGenericBitmap(GBool mmr, int w, int h,
Link Here
|
2611 |
JBIG2BitmapPtr atPtr0 = {0}, atPtr1 = {0}, atPtr2 = {0}, atPtr3 = {0}; |
2743 |
JBIG2BitmapPtr atPtr0 = {0}, atPtr1 = {0}, atPtr2 = {0}, atPtr3 = {0}; |
2612 |
int *refLine, *codingLine; |
2744 |
int *refLine, *codingLine; |
2613 |
int code1, code2, code3; |
2745 |
int code1, code2, code3; |
2614 |
int x, y, a0, pix, i, refI, codingI; |
2746 |
int x, y, a0i, b1i, blackPixels, pix, i; |
2615 |
|
2747 |
|
2616 |
bitmap = new JBIG2Bitmap(0, w, h); |
2748 |
bitmap = new JBIG2Bitmap(0, w, h); |
2617 |
bitmap->clearToZero(); |
2749 |
bitmap->clearToZero(); |
Lines 2621-2629
JBIG2Bitmap *JBIG2Stream::readGenericBitmap(GBool mmr, int w, int h,
Link Here
|
2621 |
if (mmr) { |
2753 |
if (mmr) { |
2622 |
|
2754 |
|
2623 |
mmrDecoder->reset(); |
2755 |
mmrDecoder->reset(); |
|
|
2756 |
if (w > INT_MAX - 2) { |
2757 |
error(getPos(), "Bad width in JBIG2 generic bitmap"); |
2758 |
// force a call to gmalloc(-1), which will throw an exception |
2759 |
w = -3; |
2760 |
} |
2761 |
// 0 <= codingLine[0] < codingLine[1] < ... < codingLine[n] = w |
2762 |
// ---> max codingLine size = w + 1 |
2763 |
// refLine has one extra guard entry at the end |
2764 |
// ---> max refLine size = w + 2 |
2765 |
codingLine = (int *)gmallocn(w + 1, sizeof(int)); |
2624 |
refLine = (int *)gmallocn(w + 2, sizeof(int)); |
2766 |
refLine = (int *)gmallocn(w + 2, sizeof(int)); |
2625 |
codingLine = (int *)gmallocn(w + 2, sizeof(int)); |
2767 |
codingLine[0] = w; |
2626 |
codingLine[0] = codingLine[1] = w; |
|
|
2627 |
|
2768 |
|
2628 |
for (y = 0; y < h; ++y) { |
2769 |
for (y = 0; y < h; ++y) { |
2629 |
|
2770 |
|
Lines 2631-2758
JBIG2Bitmap *JBIG2Stream::readGenericBitmap(GBool mmr, int w, int h,
Link Here
|
2631 |
for (i = 0; codingLine[i] < w; ++i) { |
2772 |
for (i = 0; codingLine[i] < w; ++i) { |
2632 |
refLine[i] = codingLine[i]; |
2773 |
refLine[i] = codingLine[i]; |
2633 |
} |
2774 |
} |
2634 |
refLine[i] = refLine[i + 1] = w; |
2775 |
refLine[i++] = w; |
|
|
2776 |
refLine[i] = w; |
2635 |
|
2777 |
|
2636 |
// decode a line |
2778 |
// decode a line |
2637 |
refI = 0; // b1 = refLine[refI] |
2779 |
codingLine[0] = 0; |
2638 |
codingI = 0; // a1 = codingLine[codingI] |
2780 |
a0i = 0; |
2639 |
a0 = 0; |
2781 |
b1i = 0; |
2640 |
do { |
2782 |
blackPixels = 0; |
|
|
2783 |
// invariant: |
2784 |
// refLine[b1i-1] <= codingLine[a0i] < refLine[b1i] < refLine[b1i+1] <= w |
2785 |
// exception at left edge: |
2786 |
// codingLine[a0i = 0] = refLine[b1i = 0] = 0 is possible |
2787 |
// exception at right edge: |
2788 |
// refLine[b1i] = refLine[b1i+1] = w is possible |
2789 |
while (codingLine[a0i] < w) { |
2641 |
code1 = mmrDecoder->get2DCode(); |
2790 |
code1 = mmrDecoder->get2DCode(); |
2642 |
switch (code1) { |
2791 |
switch (code1) { |
2643 |
case twoDimPass: |
2792 |
case twoDimPass: |
2644 |
if (refLine[refI] < w) { |
2793 |
mmrAddPixels(refLine[b1i + 1], blackPixels, codingLine, &a0i, w); |
2645 |
a0 = refLine[refI + 1]; |
2794 |
if (refLine[b1i + 1] < w) { |
2646 |
refI += 2; |
2795 |
b1i += 2; |
2647 |
} |
2796 |
} |
2648 |
break; |
2797 |
break; |
2649 |
case twoDimHoriz: |
2798 |
case twoDimHoriz: |
2650 |
if (codingI & 1) { |
2799 |
code1 = code2 = 0; |
2651 |
code1 = 0; |
2800 |
if (blackPixels) { |
2652 |
do { |
2801 |
do { |
2653 |
code1 += code3 = mmrDecoder->getBlackCode(); |
2802 |
code1 += code3 = mmrDecoder->getBlackCode(); |
2654 |
} while (code3 >= 64); |
2803 |
} while (code3 >= 64); |
2655 |
code2 = 0; |
2804 |
do { |
2656 |
do { |
2805 |
code2 += code3 = mmrDecoder->getWhiteCode(); |
2657 |
code2 += code3 = mmrDecoder->getWhiteCode(); |
2806 |
} while (code3 >= 64); |
2658 |
} while (code3 >= 64); |
2807 |
} else { |
2659 |
} else { |
2808 |
do { |
2660 |
code1 = 0; |
2809 |
code1 += code3 = mmrDecoder->getWhiteCode(); |
2661 |
do { |
2810 |
} while (code3 >= 64); |
2662 |
code1 += code3 = mmrDecoder->getWhiteCode(); |
2811 |
do { |
2663 |
} while (code3 >= 64); |
2812 |
code2 += code3 = mmrDecoder->getBlackCode(); |
2664 |
code2 = 0; |
2813 |
} while (code3 >= 64); |
2665 |
do { |
2814 |
} |
2666 |
code2 += code3 = mmrDecoder->getBlackCode(); |
2815 |
mmrAddPixels(codingLine[a0i] + code1, blackPixels, |
2667 |
} while (code3 >= 64); |
2816 |
codingLine, &a0i, w); |
2668 |
} |
2817 |
if (codingLine[a0i] < w) { |
2669 |
if (code1 > 0 || code2 > 0) { |
2818 |
mmrAddPixels(codingLine[a0i] + code2, blackPixels ^ 1, |
2670 |
a0 = codingLine[codingI++] = a0 + code1; |
2819 |
codingLine, &a0i, w); |
2671 |
a0 = codingLine[codingI++] = a0 + code2; |
2820 |
} |
2672 |
while (refLine[refI] <= a0 && refLine[refI] < w) { |
2821 |
while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < w) { |
2673 |
refI += 2; |
2822 |
b1i += 2; |
2674 |
} |
2823 |
} |
2675 |
} |
2824 |
break; |
2676 |
break; |
|
|
2677 |
case twoDimVert0: |
2678 |
a0 = codingLine[codingI++] = refLine[refI]; |
2679 |
if (refLine[refI] < w) { |
2680 |
++refI; |
2681 |
} |
2682 |
break; |
2683 |
case twoDimVertR1: |
2684 |
a0 = codingLine[codingI++] = refLine[refI] + 1; |
2685 |
if (refLine[refI] < w) { |
2686 |
++refI; |
2687 |
while (refLine[refI] <= a0 && refLine[refI] < w) { |
2688 |
refI += 2; |
2689 |
} |
2690 |
} |
2691 |
break; |
2692 |
case twoDimVertR2: |
2693 |
a0 = codingLine[codingI++] = refLine[refI] + 2; |
2694 |
if (refLine[refI] < w) { |
2695 |
++refI; |
2696 |
while (refLine[refI] <= a0 && refLine[refI] < w) { |
2697 |
refI += 2; |
2698 |
} |
2699 |
} |
2700 |
break; |
2701 |
case twoDimVertR3: |
2825 |
case twoDimVertR3: |
2702 |
a0 = codingLine[codingI++] = refLine[refI] + 3; |
2826 |
mmrAddPixels(refLine[b1i] + 3, blackPixels, codingLine, &a0i, w); |
2703 |
if (refLine[refI] < w) { |
2827 |
blackPixels ^= 1; |
2704 |
++refI; |
2828 |
if (codingLine[a0i] < w) { |
2705 |
while (refLine[refI] <= a0 && refLine[refI] < w) { |
2829 |
++b1i; |
2706 |
refI += 2; |
2830 |
while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < w) { |
2707 |
} |
2831 |
b1i += 2; |
2708 |
} |
2832 |
} |
2709 |
break; |
2833 |
} |
2710 |
case twoDimVertL1: |
2834 |
break; |
2711 |
a0 = codingLine[codingI++] = refLine[refI] - 1; |
2835 |
case twoDimVertR2: |
2712 |
if (refI > 0) { |
2836 |
mmrAddPixels(refLine[b1i] + 2, blackPixels, codingLine, &a0i, w); |
2713 |
--refI; |
2837 |
blackPixels ^= 1; |
2714 |
} else { |
2838 |
if (codingLine[a0i] < w) { |
2715 |
++refI; |
2839 |
++b1i; |
2716 |
} |
2840 |
while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < w) { |
2717 |
while (refLine[refI] <= a0 && refLine[refI] < w) { |
2841 |
b1i += 2; |
2718 |
refI += 2; |
2842 |
} |
2719 |
} |
2843 |
} |
2720 |
break; |
2844 |
break; |
2721 |
case twoDimVertL2: |
2845 |
case twoDimVertR1: |
2722 |
a0 = codingLine[codingI++] = refLine[refI] - 2; |
2846 |
mmrAddPixels(refLine[b1i] + 1, blackPixels, codingLine, &a0i, w); |
2723 |
if (refI > 0) { |
2847 |
blackPixels ^= 1; |
2724 |
--refI; |
2848 |
if (codingLine[a0i] < w) { |
2725 |
} else { |
2849 |
++b1i; |
2726 |
++refI; |
2850 |
while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < w) { |
2727 |
} |
2851 |
b1i += 2; |
2728 |
while (refLine[refI] <= a0 && refLine[refI] < w) { |
2852 |
} |
2729 |
refI += 2; |
2853 |
} |
2730 |
} |
2854 |
break; |
2731 |
break; |
2855 |
case twoDimVert0: |
|
|
2856 |
mmrAddPixels(refLine[b1i], blackPixels, codingLine, &a0i, w); |
2857 |
blackPixels ^= 1; |
2858 |
if (codingLine[a0i] < w) { |
2859 |
++b1i; |
2860 |
while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < w) { |
2861 |
b1i += 2; |
2862 |
} |
2863 |
} |
2864 |
break; |
2732 |
case twoDimVertL3: |
2865 |
case twoDimVertL3: |
2733 |
a0 = codingLine[codingI++] = refLine[refI] - 3; |
2866 |
mmrAddPixelsNeg(refLine[b1i] - 3, blackPixels, codingLine, &a0i, w); |
2734 |
if (refI > 0) { |
2867 |
blackPixels ^= 1; |
2735 |
--refI; |
2868 |
if (codingLine[a0i] < w) { |
2736 |
} else { |
2869 |
if (b1i > 0) { |
2737 |
++refI; |
2870 |
--b1i; |
2738 |
} |
2871 |
} else { |
2739 |
while (refLine[refI] <= a0 && refLine[refI] < w) { |
2872 |
++b1i; |
2740 |
refI += 2; |
2873 |
} |
2741 |
} |
2874 |
while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < w) { |
2742 |
break; |
2875 |
b1i += 2; |
|
|
2876 |
} |
2877 |
} |
2878 |
break; |
2879 |
case twoDimVertL2: |
2880 |
mmrAddPixelsNeg(refLine[b1i] - 2, blackPixels, codingLine, &a0i, w); |
2881 |
blackPixels ^= 1; |
2882 |
if (codingLine[a0i] < w) { |
2883 |
if (b1i > 0) { |
2884 |
--b1i; |
2885 |
} else { |
2886 |
++b1i; |
2887 |
} |
2888 |
while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < w) { |
2889 |
b1i += 2; |
2890 |
} |
2891 |
} |
2892 |
break; |
2893 |
case twoDimVertL1: |
2894 |
mmrAddPixelsNeg(refLine[b1i] - 1, blackPixels, codingLine, &a0i, w); |
2895 |
blackPixels ^= 1; |
2896 |
if (codingLine[a0i] < w) { |
2897 |
if (b1i > 0) { |
2898 |
--b1i; |
2899 |
} else { |
2900 |
++b1i; |
2901 |
} |
2902 |
while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < w) { |
2903 |
b1i += 2; |
2904 |
} |
2905 |
} |
2906 |
break; |
2907 |
case EOF: |
2908 |
mmrAddPixels(w, 0, codingLine, &a0i, w); |
2909 |
break; |
2743 |
default: |
2910 |
default: |
2744 |
error(getPos(), "Illegal code in JBIG2 MMR bitmap data"); |
2911 |
error(getPos(), "Illegal code in JBIG2 MMR bitmap data"); |
|
|
2912 |
mmrAddPixels(w, 0, codingLine, &a0i, w); |
2745 |
break; |
2913 |
break; |
2746 |
} |
2914 |
} |
2747 |
} while (a0 < w); |
2915 |
} |
2748 |
codingLine[codingI++] = w; |
|
|
2749 |
|
2916 |
|
2750 |
// convert the run lengths to a bitmap line |
2917 |
// convert the run lengths to a bitmap line |
2751 |
i = 0; |
2918 |
i = 0; |
2752 |
while (codingLine[i] < w) { |
2919 |
while (1) { |
2753 |
for (x = codingLine[i]; x < codingLine[i+1]; ++x) { |
2920 |
for (x = codingLine[i]; x < codingLine[i+1]; ++x) { |
2754 |
bitmap->setPixel(x, y); |
2921 |
bitmap->setPixel(x, y); |
2755 |
} |
2922 |
} |
|
|
2923 |
if (codingLine[i+1] >= w || codingLine[i+2] >= w) { |
2924 |
break; |
2925 |
} |
2756 |
i += 2; |
2926 |
i += 2; |
2757 |
} |
2927 |
} |
2758 |
} |
2928 |
} |
Lines 2800-2806
JBIG2Bitmap *JBIG2Stream::readGenericBitmap(GBool mmr, int w, int h,
Link Here
|
2800 |
ltp = !ltp; |
2970 |
ltp = !ltp; |
2801 |
} |
2971 |
} |
2802 |
if (ltp) { |
2972 |
if (ltp) { |
2803 |
bitmap->duplicateRow(y, y-1); |
2973 |
if (y > 0) { |
|
|
2974 |
bitmap->duplicateRow(y, y-1); |
2975 |
} |
2804 |
continue; |
2976 |
continue; |
2805 |
} |
2977 |
} |
2806 |
} |
2978 |
} |
Lines 3111-3116
JBIG2Bitmap *JBIG2Stream::readGenericRefinementRegion(int w, int h,
Link Here
|
3111 |
tpgrCX2 = refBitmap->nextPixel(&tpgrCXPtr2); |
3283 |
tpgrCX2 = refBitmap->nextPixel(&tpgrCXPtr2); |
3112 |
tpgrCX2 = (tpgrCX2 << 1) | refBitmap->nextPixel(&tpgrCXPtr2); |
3284 |
tpgrCX2 = (tpgrCX2 << 1) | refBitmap->nextPixel(&tpgrCXPtr2); |
3113 |
tpgrCX2 = (tpgrCX2 << 1) | refBitmap->nextPixel(&tpgrCXPtr2); |
3285 |
tpgrCX2 = (tpgrCX2 << 1) | refBitmap->nextPixel(&tpgrCXPtr2); |
|
|
3286 |
} else { |
3287 |
tpgrCXPtr0.p = tpgrCXPtr1.p = tpgrCXPtr2.p = NULL; // make gcc happy |
3288 |
tpgrCXPtr0.shift = tpgrCXPtr1.shift = tpgrCXPtr2.shift = 0; |
3289 |
tpgrCXPtr0.x = tpgrCXPtr1.x = tpgrCXPtr2.x = 0; |
3114 |
} |
3290 |
} |
3115 |
|
3291 |
|
3116 |
for (x = 0; x < w; ++x) { |
3292 |
for (x = 0; x < w; ++x) { |
Lines 3182-3187
JBIG2Bitmap *JBIG2Stream::readGenericRefinementRegion(int w, int h,
Link Here
|
3182 |
tpgrCX2 = refBitmap->nextPixel(&tpgrCXPtr2); |
3358 |
tpgrCX2 = refBitmap->nextPixel(&tpgrCXPtr2); |
3183 |
tpgrCX2 = (tpgrCX2 << 1) | refBitmap->nextPixel(&tpgrCXPtr2); |
3359 |
tpgrCX2 = (tpgrCX2 << 1) | refBitmap->nextPixel(&tpgrCXPtr2); |
3184 |
tpgrCX2 = (tpgrCX2 << 1) | refBitmap->nextPixel(&tpgrCXPtr2); |
3360 |
tpgrCX2 = (tpgrCX2 << 1) | refBitmap->nextPixel(&tpgrCXPtr2); |
|
|
3361 |
} else { |
3362 |
tpgrCXPtr0.p = tpgrCXPtr1.p = tpgrCXPtr2.p = NULL; // make gcc happy |
3363 |
tpgrCXPtr0.shift = tpgrCXPtr1.shift = tpgrCXPtr2.shift = 0; |
3364 |
tpgrCXPtr0.x = tpgrCXPtr1.x = tpgrCXPtr2.x = 0; |
3185 |
} |
3365 |
} |
3186 |
|
3366 |
|
3187 |
for (x = 0; x < w; ++x) { |
3367 |
for (x = 0; x < w; ++x) { |
Lines 3247-3252
void JBIG2Stream::readPageInfoSeg(Guint length) {
Link Here
|
3247 |
} |
3427 |
} |
3248 |
pageBitmap = new JBIG2Bitmap(0, pageW, curPageH); |
3428 |
pageBitmap = new JBIG2Bitmap(0, pageW, curPageH); |
3249 |
|
3429 |
|
|
|
3430 |
if (!pageBitmap->isOk()) { |
3431 |
delete pageBitmap; |
3432 |
pageBitmap = NULL; |
3433 |
return; |
3434 |
} |
3435 |
|
3250 |
// default pixel value |
3436 |
// default pixel value |
3251 |
if (pageDefPixel) { |
3437 |
if (pageDefPixel) { |
3252 |
pageBitmap->clearToOne(); |
3438 |
pageBitmap->clearToOne(); |