w = wA;
h = hA;
line = (wA + 7) >> 3;
- data = (Guchar *)gmalloc(h * line);
+ // need to allocate one extra guard byte for use in combine()
+ data = (Guchar *)gmalloc(h * line + 1);
+ data[h * line] = 0;
}
JBIG2Bitmap::JBIG2Bitmap(Guint segNumA, JBIG2Bitmap *bitmap):
w = bitmap->w;
h = bitmap->h;
line = bitmap->line;
- data = (Guchar *)gmalloc(h * line);
+ // need to allocate one extra guard byte for use in combine()
+ data = (Guchar *)gmalloc(h * line + 1);
memcpy(data, bitmap->data, h * line);
+ data[h * line] = 0;
}
JBIG2Bitmap::~JBIG2Bitmap() {
if (newH <= h) {
return;
}
- data = (Guchar *)grealloc(data, newH * line);
+ // need to allocate one extra guard byte for use in combine()
+ data = (Guchar *)grealloc(data, newH * line + 1);
if (pixel) {
memset(data + h * line, 0xff, (newH - h) * line);
} else {
memset(data + h * line, 0x00, (newH - h) * line);
}
h = newH;
+ data[h * line] = 0;
}
void JBIG2Bitmap::clearToZero() {
}
// right-most byte
+ // note: this last byte (src1) may not actually be used, depending
+ // on the values of s1, m1, and m2 - and in fact, it may be off
+ // the edge of the source bitmap, which means we need to allocate
+ // one extra guard byte at the end of each bitmap
dest = *destPtr;
src0 = src1;
src1 = *srcPtr++;
JBIG2Segment(segNumA)
{
size = sizeA;
- bitmaps = (JBIG2Bitmap **)gmalloc(size * sizeof(JBIG2Bitmap *));
+ bitmaps = (JBIG2Bitmap **)gmallocn(size, sizeof(JBIG2Bitmap *));
genericRegionStats = NULL;
refinementRegionStats = NULL;
}
JBIG2Segment(segNumA)
{
size = sizeA;
- bitmaps = (JBIG2Bitmap **)gmalloc(size * sizeof(JBIG2Bitmap *));
+ bitmaps = (JBIG2Bitmap **)gmallocn(size, sizeof(JBIG2Bitmap *));
}
JBIG2PatternDict::~JBIG2PatternDict() {
}
// referred-to segment numbers
- refSegs = (Guint *)gmalloc(nRefSegs * sizeof(Guint));
+ refSegs = (Guint *)gmallocn(nRefSegs, sizeof(Guint));
if (segNum <= 256) {
for (i = 0; i < nRefSegs; ++i) {
if (!readUByte(&refSegs[i])) {
// read the segment data
switch (segType) {
case 0:
- readSymbolDictSeg(segNum, segLength, refSegs, nRefSegs);
+ if (!readSymbolDictSeg(segNum, segLength, refSegs, nRefSegs)) {
+ goto syntaxError;
+ }
break;
case 4:
readTextRegionSeg(segNum, gFalse, gFalse, segLength, refSegs, nRefSegs);
return;
+ syntaxError:
+ gfree(refSegs);
+ return;
+
eofError2:
gfree(refSegs);
eofError1:
error(getPos(), "Unexpected EOF in JBIG2 stream");
}
-void JBIG2Stream::readSymbolDictSeg(Guint segNum, Guint length,
- Guint *refSegs, Guint nRefSegs) {
+GBool JBIG2Stream::readSymbolDictSeg(Guint segNum, Guint length,
+ Guint *refSegs, Guint nRefSegs) {
JBIG2SymbolDict *symbolDict;
JBIG2HuffmanTable *huffDHTable, *huffDWTable;
JBIG2HuffmanTable *huffBMSizeTable, *huffAggInstTable;
}
// get the input symbol bitmaps
- bitmaps = (JBIG2Bitmap **)gmalloc((numInputSyms + numNewSyms) *
- sizeof(JBIG2Bitmap *));
+ bitmaps = (JBIG2Bitmap **)gmallocn(numInputSyms + numNewSyms,
+ sizeof(JBIG2Bitmap *));
+ for (i = 0; i < numInputSyms + numNewSyms; ++i) {
+ bitmaps[i] = NULL;
+ }
k = 0;
inputSymbolDict = NULL;
for (i = 0; i < nRefSegs; ++i) {
// allocate symbol widths storage
symWidths = NULL;
if (huff && !refAgg) {
- symWidths = (Guint *)gmalloc(numNewSyms * sizeof(Guint));
+ symWidths = (Guint *)gmallocn(numNewSyms, sizeof(Guint));
}
symHeight = 0;
} else {
arithDecoder->decodeInt(&dh, iadhStats);
}
+ if (dh < 0 && (Guint)-dh >= symHeight) {
+ error(getPos(), "Bad delta-height value in JBIG2 symbol dictionary");
+ goto syntaxError;
+ }
symHeight += dh;
symWidth = 0;
totalWidth = 0;
break;
}
}
+ if (dw < 0 && (Guint)-dw >= symWidth) {
+ error(getPos(), "Bad delta-height value in JBIG2 symbol dictionary");
+ goto syntaxError;
+ }
symWidth += dw;
// using a collective bitmap, so don't read a bitmap here
// store the new symbol dict
segments->append(symbolDict);
- return;
+ return gTrue;
+
+ syntaxError:
+ for (i = 0; i < numNewSyms; ++i) {
+ if (bitmaps[numInputSyms + i]) {
+ delete bitmaps[numInputSyms + i];
+ }
+ }
+ gfree(bitmaps);
+ if (symWidths) {
+ gfree(symWidths);
+ }
+ return gFalse;
eofError:
error(getPos(), "Unexpected EOF in JBIG2 stream");
+ return gFalse;
}
void JBIG2Stream::readTextRegionSeg(Guint segNum, GBool imm,
codeTables = new GList();
numSyms = 0;
for (i = 0; i < nRefSegs; ++i) {
- seg = findSegment(refSegs[i]);
- if (seg->getType() == jbig2SegSymbolDict) {
- numSyms += ((JBIG2SymbolDict *)seg)->getSize();
- } else if (seg->getType() == jbig2SegCodeTable) {
- codeTables->append(seg);
+ if ((seg = findSegment(refSegs[i]))) {
+ if (seg->getType() == jbig2SegSymbolDict) {
+ numSyms += ((JBIG2SymbolDict *)seg)->getSize();
+ } else if (seg->getType() == jbig2SegCodeTable) {
+ codeTables->append(seg);
+ }
+ } else {
+ error(getPos(), "Invalid segment reference in JBIG2 text region");
}
}
symCodeLen = 0;
}
// get the symbol bitmaps
- syms = (JBIG2Bitmap **)gmalloc(numSyms * sizeof(JBIG2Bitmap *));
+ syms = (JBIG2Bitmap **)gmallocn(numSyms, sizeof(JBIG2Bitmap *));
kk = 0;
for (i = 0; i < nRefSegs; ++i) {
- seg = findSegment(refSegs[i]);
- if (seg->getType() == jbig2SegSymbolDict) {
- symbolDict = (JBIG2SymbolDict *)seg;
- for (k = 0; k < symbolDict->getSize(); ++k) {
- syms[kk++] = symbolDict->getBitmap(k);
+ if ((seg = findSegment(refSegs[i]))) {
+ if (seg->getType() == jbig2SegSymbolDict) {
+ symbolDict = (JBIG2SymbolDict *)seg;
+ for (k = 0; k < symbolDict->getSize(); ++k) {
+ syms[kk++] = symbolDict->getBitmap(k);
+ }
}
}
}
runLengthTab[35].prefixLen = 0;
runLengthTab[35].rangeLen = jbig2HuffmanEOT;
huffDecoder->buildTable(runLengthTab, 35);
- symCodeTab = (JBIG2HuffmanTable *)gmalloc((numSyms + 1) *
- sizeof(JBIG2HuffmanTable));
+ symCodeTab = (JBIG2HuffmanTable *)gmallocn(numSyms + 1,
+ sizeof(JBIG2HuffmanTable));
for (i = 0; i < numSyms; ++i) {
symCodeTab[i].val = i;
symCodeTab[i].rangeLen = 0;
symID = arithDecoder->decodeIAID(symCodeLen, iaidStats);
}
- // get the symbol bitmap
- symbolBitmap = NULL;
- if (refine) {
- if (huff) {
- ri = (int)huffDecoder->readBit();
+ if (symID >= (Guint)numSyms) {
+ error(getPos(), "Invalid symbol number in JBIG2 text region");
+ } else {
+
+ // get the symbol bitmap
+ symbolBitmap = NULL;
+ if (refine) {
+ if (huff) {
+ ri = (int)huffDecoder->readBit();
+ } else {
+ arithDecoder->decodeInt(&ri, iariStats);
+ }
} else {
- arithDecoder->decodeInt(&ri, iariStats);
+ ri = 0;
}
- } else {
- ri = 0;
- }
- if (ri) {
- if (huff) {
- huffDecoder->decodeInt(&rdw, huffRDWTable);
- huffDecoder->decodeInt(&rdh, huffRDHTable);
- huffDecoder->decodeInt(&rdx, huffRDXTable);
- huffDecoder->decodeInt(&rdy, huffRDYTable);
- huffDecoder->decodeInt(&bmSize, huffRSizeTable);
- huffDecoder->reset();
- arithDecoder->start();
+ if (ri) {
+ if (huff) {
+ huffDecoder->decodeInt(&rdw, huffRDWTable);
+ huffDecoder->decodeInt(&rdh, huffRDHTable);
+ huffDecoder->decodeInt(&rdx, huffRDXTable);
+ huffDecoder->decodeInt(&rdy, huffRDYTable);
+ huffDecoder->decodeInt(&bmSize, huffRSizeTable);
+ huffDecoder->reset();
+ arithDecoder->start();
+ } else {
+ arithDecoder->decodeInt(&rdw, iardwStats);
+ arithDecoder->decodeInt(&rdh, iardhStats);
+ arithDecoder->decodeInt(&rdx, iardxStats);
+ arithDecoder->decodeInt(&rdy, iardyStats);
+ }
+ refDX = ((rdw >= 0) ? rdw : rdw - 1) / 2 + rdx;
+ refDY = ((rdh >= 0) ? rdh : rdh - 1) / 2 + rdy;
+
+ symbolBitmap =
+ readGenericRefinementRegion(rdw + syms[symID]->getWidth(),
+ rdh + syms[symID]->getHeight(),
+ templ, gFalse, syms[symID],
+ refDX, refDY, atx, aty);
+ //~ do we need to use the bmSize value here (in Huffman mode)?
} else {
- arithDecoder->decodeInt(&rdw, iardwStats);
- arithDecoder->decodeInt(&rdh, iardhStats);
- arithDecoder->decodeInt(&rdx, iardxStats);
- arithDecoder->decodeInt(&rdy, iardyStats);
+ symbolBitmap = syms[symID];
}
- refDX = ((rdw >= 0) ? rdw : rdw - 1) / 2 + rdx;
- refDY = ((rdh >= 0) ? rdh : rdh - 1) / 2 + rdy;
-
- symbolBitmap =
- readGenericRefinementRegion(rdw + syms[symID]->getWidth(),
- rdh + syms[symID]->getHeight(),
- templ, gFalse, syms[symID],
- refDX, refDY, atx, aty);
- //~ do we need to use the bmSize value here (in Huffman mode)?
- } else {
- symbolBitmap = syms[symID];
- }
- // combine the symbol bitmap into the region bitmap
- //~ something is wrong here - refCorner shouldn't degenerate into
- //~ two cases
- bw = symbolBitmap->getWidth() - 1;
- bh = symbolBitmap->getHeight() - 1;
- if (transposed) {
- switch (refCorner) {
- case 0: // bottom left
- bitmap->combine(symbolBitmap, tt, s, combOp);
- break;
- case 1: // top left
- bitmap->combine(symbolBitmap, tt, s, combOp);
- break;
- case 2: // bottom right
- bitmap->combine(symbolBitmap, tt - bw, s, combOp);
- break;
- case 3: // top right
- bitmap->combine(symbolBitmap, tt - bw, s, combOp);
- break;
+ // combine the symbol bitmap into the region bitmap
+ //~ something is wrong here - refCorner shouldn't degenerate into
+ //~ two cases
+ bw = symbolBitmap->getWidth() - 1;
+ bh = symbolBitmap->getHeight() - 1;
+ if (transposed) {
+ switch (refCorner) {
+ case 0: // bottom left
+ bitmap->combine(symbolBitmap, tt, s, combOp);
+ break;
+ case 1: // top left
+ bitmap->combine(symbolBitmap, tt, s, combOp);
+ break;
+ case 2: // bottom right
+ bitmap->combine(symbolBitmap, tt - bw, s, combOp);
+ break;
+ case 3: // top right
+ bitmap->combine(symbolBitmap, tt - bw, s, combOp);
+ break;
+ }
+ s += bh;
+ } else {
+ switch (refCorner) {
+ case 0: // bottom left
+ bitmap->combine(symbolBitmap, s, tt - bh, combOp);
+ break;
+ case 1: // top left
+ bitmap->combine(symbolBitmap, s, tt, combOp);
+ break;
+ case 2: // bottom right
+ bitmap->combine(symbolBitmap, s, tt - bh, combOp);
+ break;
+ case 3: // top right
+ bitmap->combine(symbolBitmap, s, tt, combOp);
+ break;
+ }
+ s += bw;
}
- s += bh;
- } else {
- switch (refCorner) {
- case 0: // bottom left
- bitmap->combine(symbolBitmap, s, tt - bh, combOp);
- break;
- case 1: // top left
- bitmap->combine(symbolBitmap, s, tt, combOp);
- break;
- case 2: // bottom right
- bitmap->combine(symbolBitmap, s, tt - bh, combOp);
- break;
- case 3: // top right
- bitmap->combine(symbolBitmap, s, tt, combOp);
- break;
+ if (ri) {
+ delete symbolBitmap;
}
- s += bw;
- }
- if (ri) {
- delete symbolBitmap;
}
// next instance
}
// read the gray-scale image
- grayImg = (Guint *)gmalloc(gridW * gridH * sizeof(Guint));
+ grayImg = (Guint *)gmallocn(gridW * gridH, sizeof(Guint));
memset(grayImg, 0, gridW * gridH * sizeof(Guint));
atx[0] = templ <= 1 ? 3 : 2; aty[0] = -1;
atx[1] = -3; aty[1] = -1;
if (mmr) {
mmrDecoder->reset();
- refLine = (int *)gmalloc((w + 2) * sizeof(int));
- codingLine = (int *)gmalloc((w + 2) * sizeof(int));
+ refLine = (int *)gmallocn(w + 2, sizeof(int));
+ codingLine = (int *)gmallocn(w + 2, sizeof(int));
codingLine[0] = codingLine[1] = w;
for (y = 0; y < h; ++y) {
huffDecoder->reset();
huffTabSize = 8;
huffTab = (JBIG2HuffmanTable *)
- gmalloc(huffTabSize * sizeof(JBIG2HuffmanTable));
+ gmallocn(huffTabSize, sizeof(JBIG2HuffmanTable));
i = 0;
val = lowVal;
while (val < highVal) {
if (i == huffTabSize) {
huffTabSize *= 2;
huffTab = (JBIG2HuffmanTable *)
- grealloc(huffTab, huffTabSize * sizeof(JBIG2HuffmanTable));
+ greallocn(huffTab, huffTabSize, sizeof(JBIG2HuffmanTable));
}
huffTab[i].val = val;
huffTab[i].prefixLen = huffDecoder->readBits(prefixBits);
if (i + oob + 3 > huffTabSize) {
huffTabSize = i + oob + 3;
huffTab = (JBIG2HuffmanTable *)
- grealloc(huffTab, huffTabSize * sizeof(JBIG2HuffmanTable));
+ greallocn(huffTab, huffTabSize, sizeof(JBIG2HuffmanTable));
}
huffTab[i].val = lowVal - 1;
huffTab[i].prefixLen = huffDecoder->readBits(prefixBits);