Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
View | Details | Raw Unified | Return to bug 263028 | Differences between
and this patch

Collapse All | Expand All

(-)a/poppler/JBIG2Stream.cc (-127 / +320 lines)
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
      for ( ; j < numExSyms; ++j) symbolDict->setBitmap(j, NULL);
1833
      delete symbolDict;
1834
      goto syntaxError;
1835
    }
1782
    if (ex) {
1836
    if (ex) {
1783
      for (cnt = 0; cnt < run; ++cnt) {
1837
      for (cnt = 0; cnt < run; ++cnt) {
1784
	symbolDict->setBitmap(j++, bitmaps[i++]->copy());
1838
	symbolDict->setBitmap(j++, bitmaps[i++]->copy());
Lines 1788-1797 GBool JBIG2Stream::readSymbolDictSeg(Guint segNum, Guint length, Link Here
1788
    }
1842
    }
1789
    ex = !ex;
1843
    ex = !ex;
1790
  }
1844
  }
1791
  for ( ; j < numExSyms; ++j) {
1845
  if (j != numExSyms) {
1792
    // this should never happen but happens on PDF we don't parse
1846
    error(getPos(), "Too few symbols in JBIG2 symbol dictionary");
1793
    // correctly like bug #19702
1847
    for ( ; j < numExSyms; ++j) symbolDict->setBitmap(j, NULL);
1794
    symbolDict->setBitmap(j, NULL);
1848
    delete symbolDict;
1849
    goto syntaxError;
1795
  }
1850
  }
1796
1851
1797
  for (i = 0; i < numNewSyms; ++i) {
1852
  for (i = 0; i < numNewSyms; ++i) {
Lines 1815-1820 GBool JBIG2Stream::readSymbolDictSeg(Guint segNum, Guint length, Link Here
1815
1870
1816
  return gTrue;
1871
  return gTrue;
1817
1872
1873
 codeTableError:
1874
  error(getPos(), "Missing code table in JBIG2 symbol dictionary");
1875
  delete codeTables;
1876
1818
 syntaxError:
1877
 syntaxError:
1819
  for (i = 0; i < numNewSyms; ++i) {
1878
  for (i = 0; i < numNewSyms; ++i) {
1820
    if (bitmaps[numInputSyms + i]) {
1879
    if (bitmaps[numInputSyms + i]) {
Lines 1917-1922 void JBIG2Stream::readTextRegionSeg(Guint segNum, GBool imm, Link Here
1917
      }
1976
      }
1918
    } else {
1977
    } else {
1919
      error(getPos(), "Invalid segment reference in JBIG2 text region");
1978
      error(getPos(), "Invalid segment reference in JBIG2 text region");
1979
      delete codeTables;
1980
      return;
1920
    }
1981
    }
1921
  }
1982
  }
1922
  symCodeLen = 0;
1983
  symCodeLen = 0;
Lines 1951-1956 void JBIG2Stream::readTextRegionSeg(Guint segNum, GBool imm, Link Here
1951
    } else if (huffFS == 1) {
2012
    } else if (huffFS == 1) {
1952
      huffFSTable = huffTableG;
2013
      huffFSTable = huffTableG;
1953
    } else {
2014
    } else {
2015
      if (i >= (Guint)codeTables->getLength()) {
2016
	goto codeTableError;
2017
      }
1954
      huffFSTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
2018
      huffFSTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
1955
    }
2019
    }
1956
    if (huffDS == 0) {
2020
    if (huffDS == 0) {
Lines 1960-1965 void JBIG2Stream::readTextRegionSeg(Guint segNum, GBool imm, Link Here
1960
    } else if (huffDS == 2) {
2024
    } else if (huffDS == 2) {
1961
      huffDSTable = huffTableJ;
2025
      huffDSTable = huffTableJ;
1962
    } else {
2026
    } else {
2027
      if (i >= (Guint)codeTables->getLength()) {
2028
	goto codeTableError;
2029
      }
1963
      huffDSTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
2030
      huffDSTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
1964
    }
2031
    }
1965
    if (huffDT == 0) {
2032
    if (huffDT == 0) {
Lines 1969-1974 void JBIG2Stream::readTextRegionSeg(Guint segNum, GBool imm, Link Here
1969
    } else if (huffDT == 2) {
2036
    } else if (huffDT == 2) {
1970
      huffDTTable = huffTableM;
2037
      huffDTTable = huffTableM;
1971
    } else {
2038
    } else {
2039
      if (i >= (Guint)codeTables->getLength()) {
2040
	goto codeTableError;
2041
      }
1972
      huffDTTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
2042
      huffDTTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
1973
    }
2043
    }
1974
    if (huffRDW == 0) {
2044
    if (huffRDW == 0) {
Lines 1976-1981 void JBIG2Stream::readTextRegionSeg(Guint segNum, GBool imm, Link Here
1976
    } else if (huffRDW == 1) {
2046
    } else if (huffRDW == 1) {
1977
      huffRDWTable = huffTableO;
2047
      huffRDWTable = huffTableO;
1978
    } else {
2048
    } else {
2049
      if (i >= (Guint)codeTables->getLength()) {
2050
	goto codeTableError;
2051
      }
1979
      huffRDWTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
2052
      huffRDWTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
1980
    }
2053
    }
1981
    if (huffRDH == 0) {
2054
    if (huffRDH == 0) {
Lines 1983-1988 void JBIG2Stream::readTextRegionSeg(Guint segNum, GBool imm, Link Here
1983
    } else if (huffRDH == 1) {
2056
    } else if (huffRDH == 1) {
1984
      huffRDHTable = huffTableO;
2057
      huffRDHTable = huffTableO;
1985
    } else {
2058
    } else {
2059
      if (i >= (Guint)codeTables->getLength()) {
2060
	goto codeTableError;
2061
      }
1986
      huffRDHTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
2062
      huffRDHTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
1987
    }
2063
    }
1988
    if (huffRDX == 0) {
2064
    if (huffRDX == 0) {
Lines 1990-1995 void JBIG2Stream::readTextRegionSeg(Guint segNum, GBool imm, Link Here
1990
    } else if (huffRDX == 1) {
2066
    } else if (huffRDX == 1) {
1991
      huffRDXTable = huffTableO;
2067
      huffRDXTable = huffTableO;
1992
    } else {
2068
    } else {
2069
      if (i >= (Guint)codeTables->getLength()) {
2070
	goto codeTableError;
2071
      }
1993
      huffRDXTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
2072
      huffRDXTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
1994
    }
2073
    }
1995
    if (huffRDY == 0) {
2074
    if (huffRDY == 0) {
Lines 1997-2007 void JBIG2Stream::readTextRegionSeg(Guint segNum, GBool imm, Link Here
1997
    } else if (huffRDY == 1) {
2076
    } else if (huffRDY == 1) {
1998
      huffRDYTable = huffTableO;
2077
      huffRDYTable = huffTableO;
1999
    } else {
2078
    } else {
2079
      if (i >= (Guint)codeTables->getLength()) {
2080
	goto codeTableError;
2081
      }
2000
      huffRDYTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
2082
      huffRDYTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
2001
    }
2083
    }
2002
    if (huffRSize == 0) {
2084
    if (huffRSize == 0) {
2003
      huffRSizeTable = huffTableA;
2085
      huffRSizeTable = huffTableA;
2004
    } else {
2086
    } else {
2087
      if (i >= (Guint)codeTables->getLength()) {
2088
	goto codeTableError;
2089
      }
2005
      huffRSizeTable =
2090
      huffRSizeTable =
2006
	  ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
2091
	  ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
2007
    }
2092
    }
Lines 2098-2105 void JBIG2Stream::readTextRegionSeg(Guint segNum, GBool imm, Link Here
2098
2183
2099
  return;
2184
  return;
2100
2185
2186
 codeTableError:
2187
  error(getPos(), "Missing code table in JBIG2 text region");
2188
  gfree(codeTables);
2189
  delete syms;
2190
  return;
2191
2101
 eofError:
2192
 eofError:
2102
  error(getPos(), "Unexpected EOF in JBIG2 stream");
2193
  error(getPos(), "Unexpected EOF in JBIG2 stream");
2194
  return;
2103
}
2195
}
2104
2196
2105
JBIG2Bitmap *JBIG2Stream::readTextRegion(GBool huff, GBool refine,
2197
JBIG2Bitmap *JBIG2Stream::readTextRegion(GBool huff, GBool refine,
Lines 2134-2139 JBIG2Bitmap *JBIG2Stream::readTextRegion(GBool huff, GBool refine, Link Here
2134
2226
2135
  // allocate the bitmap
2227
  // allocate the bitmap
2136
  bitmap = new JBIG2Bitmap(0, w, h);
2228
  bitmap = new JBIG2Bitmap(0, w, h);
2229
  if (!bitmap->isOk()) {
2230
    delete bitmap;
2231
    return NULL;
2232
  }
2137
  if (defPixel) {
2233
  if (defPixel) {
2138
    bitmap->clearToOne();
2234
    bitmap->clearToOne();
2139
  } else {
2235
  } else {
Lines 2226-2232 JBIG2Bitmap *JBIG2Stream::readTextRegion(GBool huff, GBool refine, Link Here
2226
	    decodeSuccess = decodeSuccess && arithDecoder->decodeInt(&rdy, iardyStats);
2322
	    decodeSuccess = decodeSuccess && arithDecoder->decodeInt(&rdy, iardyStats);
2227
	  }
2323
	  }
2228
	  
2324
	  
2229
	  if (decodeSuccess)
2325
	  if (decodeSuccess && syms[symID])
2230
	  {
2326
	  {
2231
	    refDX = ((rdw >= 0) ? rdw : rdw - 1) / 2 + rdx;
2327
	    refDX = ((rdw >= 0) ? rdw : rdw - 1) / 2 + rdx;
2232
	    refDY = ((rdh >= 0) ? rdh : rdh - 1) / 2 + rdy;
2328
	    refDY = ((rdh >= 0) ? rdh : rdh - 1) / 2 + rdy;
Lines 2577-2583 void JBIG2Stream::readGenericRegionSeg(Guint segNum, GBool imm, Link Here
2577
2673
2578
  // read the bitmap
2674
  // read the bitmap
2579
  bitmap = readGenericBitmap(mmr, w, h, templ, tpgdOn, gFalse,
2675
  bitmap = readGenericBitmap(mmr, w, h, templ, tpgdOn, gFalse,
2580
			     NULL, atx, aty, mmr ? 0 : length - 18);
2676
			     NULL, atx, aty, mmr ? length - 18 : 0);
2677
  if (!bitmap)
2678
    return;
2581
2679
2582
  // combine the region bitmap into the page bitmap
2680
  // combine the region bitmap into the page bitmap
2583
  if (imm) {
2681
  if (imm) {
Lines 2599-2604 void JBIG2Stream::readGenericRegionSeg(Guint segNum, GBool imm, Link Here
2599
  error(getPos(), "Unexpected EOF in JBIG2 stream");
2697
  error(getPos(), "Unexpected EOF in JBIG2 stream");
2600
}
2698
}
2601
2699
2700
inline void JBIG2Stream::mmrAddPixels(int a1, int blackPixels,
2701
				      int *codingLine, int *a0i, int w) {
2702
  if (a1 > codingLine[*a0i]) {
2703
    if (a1 > w) {
2704
      error(getPos(), "JBIG2 MMR row is wrong length ({0:d})", a1);
2705
      a1 = w;
2706
    }
2707
    if ((*a0i & 1) ^ blackPixels) {
2708
      ++*a0i;
2709
    }
2710
    codingLine[*a0i] = a1;
2711
  }
2712
}
2713
2714
inline void JBIG2Stream::mmrAddPixelsNeg(int a1, int blackPixels,
2715
					 int *codingLine, int *a0i, int w) {
2716
  if (a1 > codingLine[*a0i]) {
2717
    if (a1 > w) {
2718
      error(getPos(), "JBIG2 MMR row is wrong length ({0:d})", a1);
2719
      a1 = w;
2720
    }
2721
    if ((*a0i & 1) ^ blackPixels) {
2722
      ++*a0i;
2723
    }
2724
    codingLine[*a0i] = a1;
2725
  } else if (a1 < codingLine[*a0i]) {
2726
    if (a1 < 0) {
2727
      error(getPos(), "Invalid JBIG2 MMR code");
2728
      a1 = 0;
2729
    }
2730
    while (*a0i > 0 && a1 <= codingLine[*a0i - 1]) {
2731
      --*a0i;
2732
    }
2733
    codingLine[*a0i] = a1;
2734
  }
2735
}
2736
2602
JBIG2Bitmap *JBIG2Stream::readGenericBitmap(GBool mmr, int w, int h,
2737
JBIG2Bitmap *JBIG2Stream::readGenericBitmap(GBool mmr, int w, int h,
2603
					    int templ, GBool tpgdOn,
2738
					    int templ, GBool tpgdOn,
2604
					    GBool useSkip, JBIG2Bitmap *skip,
2739
					    GBool useSkip, JBIG2Bitmap *skip,
Lines 2611-2619 JBIG2Bitmap *JBIG2Stream::readGenericBitmap(GBool mmr, int w, int h, Link Here
2611
  JBIG2BitmapPtr atPtr0 = {0}, atPtr1 = {0}, atPtr2 = {0}, atPtr3 = {0};
2746
  JBIG2BitmapPtr atPtr0 = {0}, atPtr1 = {0}, atPtr2 = {0}, atPtr3 = {0};
2612
  int *refLine, *codingLine;
2747
  int *refLine, *codingLine;
2613
  int code1, code2, code3;
2748
  int code1, code2, code3;
2614
  int x, y, a0, pix, i, refI, codingI;
2749
  int x, y, a0i, b1i, blackPixels, pix, i;
2615
2750
2616
  bitmap = new JBIG2Bitmap(0, w, h);
2751
  bitmap = new JBIG2Bitmap(0, w, h);
2752
  if (!bitmap->isOk()) {
2753
    delete bitmap;
2754
    return NULL;
2755
  }
2617
  bitmap->clearToZero();
2756
  bitmap->clearToZero();
2618
2757
2619
  //----- MMR decode
2758
  //----- MMR decode
Lines 2621-2629 JBIG2Bitmap *JBIG2Stream::readGenericBitmap(GBool mmr, int w, int h, Link Here
2621
  if (mmr) {
2760
  if (mmr) {
2622
2761
2623
    mmrDecoder->reset();
2762
    mmrDecoder->reset();
2763
    if (w > INT_MAX - 2) {
2764
      error(getPos(), "Bad width in JBIG2 generic bitmap");
2765
      // force a call to gmalloc(-1), which will throw an exception
2766
      w = -3;
2767
    }
2768
    // 0 <= codingLine[0] < codingLine[1] < ... < codingLine[n] = w
2769
    // ---> max codingLine size = w + 1
2770
    // refLine has one extra guard entry at the end
2771
    // ---> max refLine size = w + 2
2772
    codingLine = (int *)gmallocn(w + 1, sizeof(int));
2624
    refLine = (int *)gmallocn(w + 2, sizeof(int));
2773
    refLine = (int *)gmallocn(w + 2, sizeof(int));
2625
    codingLine = (int *)gmallocn(w + 2, sizeof(int));
2774
    codingLine[0] = w;
2626
    codingLine[0] = codingLine[1] = w;
2627
2775
2628
    for (y = 0; y < h; ++y) {
2776
    for (y = 0; y < h; ++y) {
2629
2777
Lines 2631-2758 JBIG2Bitmap *JBIG2Stream::readGenericBitmap(GBool mmr, int w, int h, Link Here
2631
      for (i = 0; codingLine[i] < w; ++i) {
2779
      for (i = 0; codingLine[i] < w; ++i) {
2632
	refLine[i] = codingLine[i];
2780
	refLine[i] = codingLine[i];
2633
      }
2781
      }
2634
      refLine[i] = refLine[i + 1] = w;
2782
      refLine[i++] = w;
2783
      refLine[i] = w;
2635
2784
2636
      // decode a line
2785
      // decode a line
2637
      refI = 0;     // b1 = refLine[refI]
2786
      codingLine[0] = 0;
2638
      codingI = 0;  // a1 = codingLine[codingI]
2787
      a0i = 0;
2639
      a0 = 0;
2788
      b1i = 0;
2640
      do {
2789
      blackPixels = 0;
2790
      // invariant:
2791
      // refLine[b1i-1] <= codingLine[a0i] < refLine[b1i] < refLine[b1i+1] <= w
2792
      // exception at left edge:
2793
      //   codingLine[a0i = 0] = refLine[b1i = 0] = 0 is possible
2794
      // exception at right edge:
2795
      //   refLine[b1i] = refLine[b1i+1] = w is possible
2796
      while (codingLine[a0i] < w) {
2641
	code1 = mmrDecoder->get2DCode();
2797
	code1 = mmrDecoder->get2DCode();
2642
	switch (code1) {
2798
	switch (code1) {
2643
	case twoDimPass:
2799
	case twoDimPass:
2644
	  if (refLine[refI] < w) {
2800
          mmrAddPixels(refLine[b1i + 1], blackPixels, codingLine, &a0i, w);
2645
	    a0 = refLine[refI + 1];
2801
          if (refLine[b1i + 1] < w) {
2646
	    refI += 2;
2802
            b1i += 2;
2647
	  }
2803
          }
2648
	  break;
2804
          break;
2649
	case twoDimHoriz:
2805
	case twoDimHoriz:
2650
	  if (codingI & 1) {
2806
          code1 = code2 = 0;
2651
	    code1 = 0;
2807
          if (blackPixels) {
2652
	    do {
2808
            do {
2653
	      code1 += code3 = mmrDecoder->getBlackCode();
2809
              code1 += code3 = mmrDecoder->getBlackCode();
2654
	    } while (code3 >= 64);
2810
            } while (code3 >= 64);
2655
	    code2 = 0;
2811
            do {
2656
	    do {
2812
              code2 += code3 = mmrDecoder->getWhiteCode();
2657
	      code2 += code3 = mmrDecoder->getWhiteCode();
2813
            } while (code3 >= 64);
2658
	    } while (code3 >= 64);
2814
          } else {
2659
	  } else {
2815
            do {
2660
	    code1 = 0;
2816
              code1 += code3 = mmrDecoder->getWhiteCode();
2661
	    do {
2817
            } while (code3 >= 64);
2662
	      code1 += code3 = mmrDecoder->getWhiteCode();
2818
            do {
2663
	    } while (code3 >= 64);
2819
              code2 += code3 = mmrDecoder->getBlackCode();
2664
	    code2 = 0;
2820
            } while (code3 >= 64);
2665
	    do {
2821
          }
2666
	      code2 += code3 = mmrDecoder->getBlackCode();
2822
          mmrAddPixels(codingLine[a0i] + code1, blackPixels,
2667
	    } while (code3 >= 64);
2823
		       codingLine, &a0i, w);
2668
	  }
2824
          if (codingLine[a0i] < w) {
2669
	  if (code1 > 0 || code2 > 0) {
2825
            mmrAddPixels(codingLine[a0i] + code2, blackPixels ^ 1,
2670
	    a0 = codingLine[codingI++] = a0 + code1;
2826
			 codingLine, &a0i, w);
2671
	    a0 = codingLine[codingI++] = a0 + code2;
2827
          }
2672
	    while (refLine[refI] <= a0 && refLine[refI] < w) {
2828
          while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < w) {
2673
	      refI += 2;
2829
            b1i += 2;
2674
	    }
2830
          }
2675
	  }
2831
          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:
2832
	case twoDimVertR3:
2702
	  a0 = codingLine[codingI++] = refLine[refI] + 3;
2833
          mmrAddPixels(refLine[b1i] + 3, blackPixels, codingLine, &a0i, w);
2703
	  if (refLine[refI] < w) {
2834
          blackPixels ^= 1;
2704
	    ++refI;
2835
          if (codingLine[a0i] < w) {
2705
	    while (refLine[refI] <= a0 && refLine[refI] < w) {
2836
            ++b1i;
2706
	      refI += 2;
2837
            while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < w) {
2707
	    }
2838
              b1i += 2;
2708
	  }
2839
            }
2709
	  break;
2840
          }
2710
	case twoDimVertL1:
2841
          break;
2711
	  a0 = codingLine[codingI++] = refLine[refI] - 1;
2842
	case twoDimVertR2:
2712
	  if (refI > 0) {
2843
          mmrAddPixels(refLine[b1i] + 2, blackPixels, codingLine, &a0i, w);
2713
	    --refI;
2844
          blackPixels ^= 1;
2714
	  } else {
2845
          if (codingLine[a0i] < w) {
2715
	    ++refI;
2846
            ++b1i;
2716
	  }
2847
            while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < w) {
2717
	  while (refLine[refI] <= a0 && refLine[refI] < w) {
2848
              b1i += 2;
2718
	    refI += 2;
2849
            }
2719
	  }
2850
          }
2720
	  break;
2851
          break;
2721
	case twoDimVertL2:
2852
	case twoDimVertR1:
2722
	  a0 = codingLine[codingI++] = refLine[refI] - 2;
2853
          mmrAddPixels(refLine[b1i] + 1, blackPixels, codingLine, &a0i, w);
2723
	  if (refI > 0) {
2854
          blackPixels ^= 1;
2724
	    --refI;
2855
          if (codingLine[a0i] < w) {
2725
	  } else {
2856
            ++b1i;
2726
	    ++refI;
2857
            while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < w) {
2727
	  }
2858
              b1i += 2;
2728
	  while (refLine[refI] <= a0 && refLine[refI] < w) {
2859
            }
2729
	    refI += 2;
2860
          }
2730
	  }
2861
          break;
2731
	  break;
2862
	case twoDimVert0:
2863
          mmrAddPixels(refLine[b1i], blackPixels, codingLine, &a0i, w);
2864
          blackPixels ^= 1;
2865
          if (codingLine[a0i] < w) {
2866
            ++b1i;
2867
            while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < w) {
2868
              b1i += 2;
2869
            }
2870
          }
2871
          break;
2732
	case twoDimVertL3:
2872
	case twoDimVertL3:
2733
	  a0 = codingLine[codingI++] = refLine[refI] - 3;
2873
          mmrAddPixelsNeg(refLine[b1i] - 3, blackPixels, codingLine, &a0i, w);
2734
	  if (refI > 0) {
2874
          blackPixels ^= 1;
2735
	    --refI;
2875
          if (codingLine[a0i] < w) {
2736
	  } else {
2876
            if (b1i > 0) {
2737
	    ++refI;
2877
              --b1i;
2738
	  }
2878
            } else {
2739
	  while (refLine[refI] <= a0 && refLine[refI] < w) {
2879
              ++b1i;
2740
	    refI += 2;
2880
            }
2741
	  }
2881
            while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < w) {
2742
	  break;
2882
              b1i += 2;
2883
            }
2884
          }
2885
          break;
2886
	case twoDimVertL2:
2887
          mmrAddPixelsNeg(refLine[b1i] - 2, blackPixels, codingLine, &a0i, w);
2888
          blackPixels ^= 1;
2889
          if (codingLine[a0i] < w) {
2890
            if (b1i > 0) {
2891
              --b1i;
2892
            } else {
2893
              ++b1i;
2894
            }
2895
            while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < w) {
2896
              b1i += 2;
2897
            }
2898
          }
2899
          break;
2900
	case twoDimVertL1:
2901
          mmrAddPixelsNeg(refLine[b1i] - 1, blackPixels, codingLine, &a0i, w);
2902
          blackPixels ^= 1;
2903
          if (codingLine[a0i] < w) {
2904
            if (b1i > 0) {
2905
              --b1i;
2906
            } else {
2907
              ++b1i;
2908
            }
2909
            while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < w) {
2910
              b1i += 2;
2911
            }
2912
          }
2913
          break;
2914
	case EOF:
2915
          mmrAddPixels(w, 0, codingLine, &a0i, w);
2916
          break;
2743
	default:
2917
	default:
2744
	  error(getPos(), "Illegal code in JBIG2 MMR bitmap data");
2918
	  error(getPos(), "Illegal code in JBIG2 MMR bitmap data");
2919
          mmrAddPixels(w, 0, codingLine, &a0i, w);
2745
	  break;
2920
	  break;
2746
	}
2921
	}
2747
      } while (a0 < w);
2922
      }
2748
      codingLine[codingI++] = w;
2749
2923
2750
      // convert the run lengths to a bitmap line
2924
      // convert the run lengths to a bitmap line
2751
      i = 0;
2925
      i = 0;
2752
      while (codingLine[i] < w) {
2926
      while (1) {
2753
	for (x = codingLine[i]; x < codingLine[i+1]; ++x) {
2927
	for (x = codingLine[i]; x < codingLine[i+1]; ++x) {
2754
	  bitmap->setPixel(x, y);
2928
	  bitmap->setPixel(x, y);
2755
	}
2929
	}
2930
	if (codingLine[i+1] >= w || codingLine[i+2] >= w) {
2931
	  break;
2932
	}
2756
	i += 2;
2933
	i += 2;
2757
      }
2934
      }
2758
    }
2935
    }
Lines 2800-2806 JBIG2Bitmap *JBIG2Stream::readGenericBitmap(GBool mmr, int w, int h, Link Here
2800
	  ltp = !ltp;
2977
	  ltp = !ltp;
2801
	}
2978
	}
2802
	if (ltp) {
2979
	if (ltp) {
2803
	  bitmap->duplicateRow(y, y-1);
2980
	  if (y > 0) {
2981
	    bitmap->duplicateRow(y, y-1);
2982
	  }
2804
	  continue;
2983
	  continue;
2805
	}
2984
	}
2806
      }
2985
      }
Lines 3111-3116 JBIG2Bitmap *JBIG2Stream::readGenericRefinementRegion(int w, int h, Link Here
3111
	tpgrCX2 = refBitmap->nextPixel(&tpgrCXPtr2);
3290
	tpgrCX2 = refBitmap->nextPixel(&tpgrCXPtr2);
3112
	tpgrCX2 = (tpgrCX2 << 1) | refBitmap->nextPixel(&tpgrCXPtr2);
3291
	tpgrCX2 = (tpgrCX2 << 1) | refBitmap->nextPixel(&tpgrCXPtr2);
3113
	tpgrCX2 = (tpgrCX2 << 1) | refBitmap->nextPixel(&tpgrCXPtr2);
3292
	tpgrCX2 = (tpgrCX2 << 1) | refBitmap->nextPixel(&tpgrCXPtr2);
3293
      } else {
3294
	tpgrCXPtr0.p = tpgrCXPtr1.p = tpgrCXPtr2.p = NULL; // make gcc happy
3295
	tpgrCXPtr0.shift = tpgrCXPtr1.shift = tpgrCXPtr2.shift = 0;
3296
	tpgrCXPtr0.x = tpgrCXPtr1.x = tpgrCXPtr2.x = 0;
3114
      }
3297
      }
3115
3298
3116
      for (x = 0; x < w; ++x) {
3299
      for (x = 0; x < w; ++x) {
Lines 3182-3187 JBIG2Bitmap *JBIG2Stream::readGenericRefinementRegion(int w, int h, Link Here
3182
	tpgrCX2 = refBitmap->nextPixel(&tpgrCXPtr2);
3365
	tpgrCX2 = refBitmap->nextPixel(&tpgrCXPtr2);
3183
	tpgrCX2 = (tpgrCX2 << 1) | refBitmap->nextPixel(&tpgrCXPtr2);
3366
	tpgrCX2 = (tpgrCX2 << 1) | refBitmap->nextPixel(&tpgrCXPtr2);
3184
	tpgrCX2 = (tpgrCX2 << 1) | refBitmap->nextPixel(&tpgrCXPtr2);
3367
	tpgrCX2 = (tpgrCX2 << 1) | refBitmap->nextPixel(&tpgrCXPtr2);
3368
      } else {
3369
	tpgrCXPtr0.p = tpgrCXPtr1.p = tpgrCXPtr2.p = NULL; // make gcc happy
3370
	tpgrCXPtr0.shift = tpgrCXPtr1.shift = tpgrCXPtr2.shift = 0;
3371
	tpgrCXPtr0.x = tpgrCXPtr1.x = tpgrCXPtr2.x = 0;
3185
      }
3372
      }
3186
3373
3187
      for (x = 0; x < w; ++x) {
3374
      for (x = 0; x < w; ++x) {
Lines 3247-3252 void JBIG2Stream::readPageInfoSeg(Guint length) { Link Here
3247
  }
3434
  }
3248
  pageBitmap = new JBIG2Bitmap(0, pageW, curPageH);
3435
  pageBitmap = new JBIG2Bitmap(0, pageW, curPageH);
3249
3436
3437
  if (!pageBitmap->isOk()) {
3438
    delete pageBitmap;
3439
    pageBitmap = NULL;
3440
    return;
3441
  }
3442
  
3250
  // default pixel value
3443
  // default pixel value
3251
  if (pageDefPixel) {
3444
  if (pageDefPixel) {
3252
    pageBitmap->clearToOne();
3445
    pageBitmap->clearToOne();
(-)a/poppler/JBIG2Stream.h (+4 lines)
Lines 76-81 private: Link Here
76
			     Guint *refSegs, Guint nRefSegs);
76
			     Guint *refSegs, Guint nRefSegs);
77
  void readGenericRegionSeg(Guint segNum, GBool imm,
77
  void readGenericRegionSeg(Guint segNum, GBool imm,
78
			    GBool lossless, Guint length);
78
			    GBool lossless, Guint length);
79
  void mmrAddPixels(int a1, int blackPixels,
80
		    int *codingLine, int *a0i, int w);
81
  void mmrAddPixelsNeg(int a1, int blackPixels,
82
		       int *codingLine, int *a0i, int w);
79
  JBIG2Bitmap *readGenericBitmap(GBool mmr, int w, int h,
83
  JBIG2Bitmap *readGenericBitmap(GBool mmr, int w, int h,
80
				 int templ, GBool tpgdOn,
84
				 int templ, GBool tpgdOn,
81
				 GBool useSkip, JBIG2Bitmap *skip,
85
				 GBool useSkip, JBIG2Bitmap *skip,

Return to bug 263028