Commit message: segExtraBytes is a goffset not an int so use lld

Fixes KDE bug #328511
CVE: CVE-2013-7296
CWE: CWE-119
Vulnerability description: The JBIG2Stream::readSegments method in JBIG2Stream.cc in Poppler before 0.24.5 does not use the correct specifier within a format string, which allows context-dependent attackers to cause a denial of service (segmentation fault and application crash) via a crafted PDF file.

Project: poppler

JBIG2Bitmap::JBIG2Bitmap(Guint segNumA, JBIG2Bitmap *bitmap):
  JBIG2Segment(segNumA)
{
  if (unlikely(bitmap == NULL)) {
    error(errSyntaxError, -1, "NULL bitmap in JBIG2Bitmap");
    w = h = line = 0;
    data = NULL;
    return;
  }

  w = bitmap->w;
  h = bitmap->h;
  line = bitmap->line;

  if (w <= 0 || h <= 0 || line <= 0 || h >= (INT_MAX - 1) / line) {
    error(errSyntaxError, -1, "invalid width/height");
    data = NULL;
    return;
  }
  data = (Guchar *)gmalloc(h * line + 1);
  memcpy(data, bitmap->data, h * line);
  data[h * line] = 0;
}

Project: poppler

JBIG2PatternDict::JBIG2PatternDict(Guint segNumA, Guint sizeA):
  JBIG2Segment(segNumA)
{
  bitmaps = (JBIG2Bitmap **)gmallocn_checkoverflow(sizeA, sizeof(JBIG2Bitmap *));
  if (bitmaps) {
    size = sizeA;
  } else {
    size = 0;
    error(errSyntaxError, -1, "JBIG2PatternDict: can't allocate bitmaps");
  }
}

Project: poppler

JBIG2SymbolDict::JBIG2SymbolDict(Guint segNumA, Guint sizeA):
  JBIG2Segment(segNumA)
{
  Guint i;

  size = sizeA;
  bitmaps = (JBIG2Bitmap **)gmallocn_checkoverflow(size, sizeof(JBIG2Bitmap *));
  if (!bitmaps) size = 0;
  for (i = 0; i < size; ++i) {
    bitmaps[i] = NULL;
  }
  genericRegionStats = NULL;
  refinementRegionStats = NULL;
}

Project: poppler

void JBIG2Bitmap::combine(JBIG2Bitmap *bitmap, int x, int y,
			  Guint combOp) {
  int x0, x1, y0, y1, xx, yy;
  Guchar *srcPtr, *destPtr;
  Guint src0, src1, src, dest, s1, s2, m1, m2, m3;
  GBool oneByte;

  if (y < -0x7fffffff) {
    return;
  }
  if (y < 0) {
    y0 = -y;
  } else {
    y0 = 0;
  }
  if (y + bitmap->h > h) {
    y1 = h - y;
  } else {
    y1 = bitmap->h;
  }
  if (y0 >= y1) {
    return;
  }

  if (x >= 0) {
    x0 = x & ~7;
  } else {
    x0 = 0;
  }
  x1 = x + bitmap->w;
  if (x1 > w) {
    x1 = w;
  }
  if (x0 >= x1) {
    return;
  }

  s1 = x & 7;
  s2 = 8 - s1;
  m1 = 0xff >> (x1 & 7);
  m2 = 0xff << (((x1 & 7) == 0) ? 0 : 8 - (x1 & 7));
  m3 = (0xff >> s1) & m2;

  oneByte = x0 == ((x1 - 1) & ~7);

  for (yy = y0; yy < y1; ++yy) {

    if (oneByte) {
      if (x >= 0) {
	destPtr = data + (y + yy) * line + (x >> 3);
	srcPtr = bitmap->data + yy * bitmap->line;
	dest = *destPtr;
	src1 = *srcPtr;
	switch (combOp) {
	case 0: // or
	  dest |= (src1 >> s1) & m2;
	  break;
	case 1: // and
	  dest &= ((0xff00 | src1) >> s1) | m1;
	  break;
	case 2: // xor
	  dest ^= (src1 >> s1) & m2;
	  break;
	case 3: // xnor
	  dest ^= ((src1 ^ 0xff) >> s1) & m2;
	  break;
	case 4: // replace
	  dest = (dest & ~m3) | ((src1 >> s1) & m3);
	  break;
	}
	*destPtr = dest;
      } else {
	destPtr = data + (y + yy) * line;
	srcPtr = bitmap->data + yy * bitmap->line + (-x >> 3);
	dest = *destPtr;
	src1 = *srcPtr;
	switch (combOp) {
	case 0: // or
	  dest |= src1 & m2;
	  break;
	case 1: // and
	  dest &= src1 | m1;
	  break;
	case 2: // xor
	  dest ^= src1 & m2;
	  break;
	case 3: // xnor
	  dest ^= (src1 ^ 0xff) & m2;
	  break;
	case 4: // replace
	  dest = (src1 & m2) | (dest & m1);
	  break;
	}
	*destPtr = dest;
      }

    } else {

      if (x >= 0) {
	destPtr = data + (y + yy) * line + (x >> 3);
	srcPtr = bitmap->data + yy * bitmap->line;
	src1 = *srcPtr++;
	dest = *destPtr;
	switch (combOp) {
	case 0: // or
	  dest |= src1 >> s1;
	  break;
	case 1: // and
	  dest &= (0xff00 | src1) >> s1;
	  break;
	case 2: // xor
	  dest ^= src1 >> s1;
	  break;
	case 3: // xnor
	  dest ^= (src1 ^ 0xff) >> s1;
	  break;
	case 4: // replace
	  dest = (dest & (0xff << s2)) | (src1 >> s1);
	  break;
	}
	*destPtr++ = dest;
	xx = x0 + 8;
      } else {
	destPtr = data + (y + yy) * line;
	srcPtr = bitmap->data + yy * bitmap->line + (-x >> 3);
	src1 = *srcPtr++;
	xx = x0;
      }

      for (; xx < x1 - 8; xx += 8) {
	dest = *destPtr;
	src0 = src1;
	src1 = *srcPtr++;
	src = (((src0 << 8) | src1) >> s1) & 0xff;
	switch (combOp) {
	case 0: // or
	  dest |= src;
	  break;
	case 1: // and
	  dest &= src;
	  break;
	case 2: // xor
	  dest ^= src;
	  break;
	case 3: // xnor
	  dest ^= src ^ 0xff;
	  break;
	case 4: // replace
	  dest = src;
	  break;
	}
	*destPtr++ = dest;
      }

      dest = *destPtr;
      src0 = src1;
      src1 = *srcPtr++;
      src = (((src0 << 8) | src1) >> s1) & 0xff;
      switch (combOp) {
      case 0: // or
	dest |= src & m2;
	break;
      case 1: // and
	dest &= src | m1;
	break;
      case 2: // xor
	dest ^= src & m2;
	break;
      case 3: // xnor
	dest ^= (src ^ 0xff) & m2;
	break;
      case 4: // replace
	dest = (src & m2) | (dest & m1);
	break;
      }
      *destPtr = dest;
    }
  }
}

Project: poppler

void JBIG2Bitmap::expand(int newH, Guint pixel) {
  if (newH <= h || line <= 0 || newH >= (INT_MAX - 1) / line) {
    error(errSyntaxError, -1, "invalid width/height");
    gfree(data);
    data = NULL;
    return;
  }
  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;
}

Project: poppler

int JBIG2MMRDecoder::get2DCode() {
  const CCITTCode *p;

  if (bufLen == 0) {
    buf = str->getChar() & 0xff;
    bufLen = 8;
    ++nBytesRead;
    p = &twoDimTab1[(buf >> 1) & 0x7f];
  } else if (bufLen == 8) {
    p = &twoDimTab1[(buf >> 1) & 0x7f];
  } else {
    p = &twoDimTab1[(buf << (7 - bufLen)) & 0x7f];
    if (p->bits < 0 || p->bits > (int)bufLen) {
      buf = (buf << 8) | (str->getChar() & 0xff);
      bufLen += 8;
      ++nBytesRead;
      p = &twoDimTab1[(buf >> (bufLen - 7)) & 0x7f];
    }
  }
  if (p->bits < 0) {
    error(errSyntaxError, str->getPos(), "Bad two dim code in JBIG2 MMR stream");
    return EOF;
  }
  bufLen -= p->bits;
  return p->n;
}

Project: poppler

  JBIG2Bitmap *getBitmap(Guint idx) { return (idx < size) ? bitmaps[idx] : NULL; }

Project: poppler

int JBIG2MMRDecoder::getBlackCode() {
  const CCITTCode *p;
  Guint code;

  if (bufLen == 0) {
    buf = str->getChar() & 0xff;
    bufLen = 8;
    ++nBytesRead;
  }
  while (1) {
    if (bufLen >= 10 && ((buf >> (bufLen - 6)) & 0x3f) == 0) {
      if (bufLen <= 13) {
	code = buf << (13 - bufLen);
      } else {
	code = buf >> (bufLen - 13);
      }
      p = &blackTab1[code & 0x7f];
    } else if (bufLen >= 7 && ((buf >> (bufLen - 4)) & 0x0f) == 0 &&
	       ((buf >> (bufLen - 6)) & 0x03) != 0) {
      if (bufLen <= 12) {
	code = buf << (12 - bufLen);
      } else {
	code = buf >> (bufLen - 12);
      }
      if (unlikely((code & 0xff) < 64)) {
        break;
      }
      p = &blackTab2[(code & 0xff) - 64];
    } else {
      if (bufLen <= 6) {
	code = buf << (6 - bufLen);
      } else {
	code = buf >> (bufLen - 6);
      }
      p = &blackTab3[code & 0x3f];
    }
    if (p->bits > 0 && p->bits <= (int)bufLen) {
      bufLen -= p->bits;
      return p->n;
    }
    if (bufLen >= 13) {
      break;
    }
    buf = (buf << 8) | (str->getChar() & 0xff);
    bufLen += 8;
    ++nBytesRead;
  }
  error(errSyntaxError, str->getPos(), "Bad black code in JBIG2 MMR stream");
  --bufLen;
  return 1;
}

Project: poppler

int JBIG2Stream::getChars(int nChars, Guchar *buffer) {
  int n, i;

  if (nChars <= 0) {
    return 0;
  }
  if (dataEnd - dataPtr < nChars) {
    n = (int)(dataEnd - dataPtr);
  } else {
    n = nChars;
  }
  for (i = 0; i < n; ++i) {
    buffer[i] = *dataPtr++ ^ 0xff;
  }
  return n;
}

Project: poppler

  int getLineSize() { return line; }

Project: poppler

inline void JBIG2Bitmap::getPixelPtr(int x, int y, JBIG2BitmapPtr *ptr) {
  if (y < 0 || y >= h || x >= w) {
    ptr->p = NULL;
    ptr->shift = 0; // make gcc happy
    ptr->x = 0; // make gcc happy
  } else if (x < 0) {
    ptr->p = &data[y * line];
    ptr->shift = 7;
    ptr->x = x;
  } else {
    ptr->p = &data[y * line + (x >> 3)];
    ptr->shift = 7 - (x & 7);
    ptr->x = x;
  }
}

Project: poppler

JBIG2Bitmap *JBIG2Bitmap::getSlice(Guint x, Guint y, Guint wA, Guint hA) {
  JBIG2Bitmap *slice;
  Guint xx, yy;

  slice = new JBIG2Bitmap(0, wA, hA);
  if (slice->isOk()) {
    slice->clearToZero();
    for (yy = 0; yy < hA; ++yy) {
      for (xx = 0; xx < wA; ++xx) {
        if (getPixel(x + xx, y + yy)) {
	  slice->setPixel(xx, yy);
        }
      }
    }
  } else {
    delete slice;
    slice = NULL;
  }
  return slice;
}

Project: poppler

  GBool isOk() { return bitmaps != NULL; }

Project: poppler
File: JBIG2Stream.cc

inline void JBIG2Stream::mmrAddPixels(int a1, int blackPixels,
				      int *codingLine, int *a0i, int w) {
  if (a1 > codingLine[*a0i]) {
    if (a1 > w) {
      error(errSyntaxError, curStr->getPos(), "JBIG2 MMR row is wrong length ({0:d})", a1);
      a1 = w;
    }
    if ((*a0i & 1) ^ blackPixels) {
      ++*a0i;
    }
    codingLine[*a0i] = a1;
  }
}

Project: poppler

void JBIG2Stream::readCodeTableSeg(Guint segNum, Guint length) {
  JBIG2HuffmanTable *huffTab;
  Guint flags, oob, prefixBits, rangeBits;
  int lowVal, highVal, val;
  Guint huffTabSize, i;

  if (!readUByte(&flags) || !readLong(&lowVal) || !readLong(&highVal)) {
    goto eofError;
  }
  oob = flags & 1;
  prefixBits = ((flags >> 1) & 7) + 1;
  rangeBits = ((flags >> 4) & 7) + 1;

  huffDecoder->reset();
  huffTabSize = 8;
  huffTab = (JBIG2HuffmanTable *)
                gmallocn(huffTabSize, sizeof(JBIG2HuffmanTable));
  i = 0;
  val = lowVal;
  while (val < highVal) {
    if (i == huffTabSize) {
      huffTabSize *= 2;
      huffTab = (JBIG2HuffmanTable *)
	            greallocn(huffTab, huffTabSize, sizeof(JBIG2HuffmanTable));
    }
    huffTab[i].val = val;
    huffTab[i].prefixLen = huffDecoder->readBits(prefixBits);
    huffTab[i].rangeLen = huffDecoder->readBits(rangeBits);
    val += 1 << huffTab[i].rangeLen;
    ++i;
  }
  if (i + oob + 3 > huffTabSize) {
    huffTabSize = i + oob + 3;
    huffTab = (JBIG2HuffmanTable *)
                  greallocn(huffTab, huffTabSize, sizeof(JBIG2HuffmanTable));
  }
  huffTab[i].val = lowVal - 1;
  huffTab[i].prefixLen = huffDecoder->readBits(prefixBits);
  huffTab[i].rangeLen = jbig2HuffmanLOW;
  ++i;
  huffTab[i].val = highVal;
  huffTab[i].prefixLen = huffDecoder->readBits(prefixBits);
  huffTab[i].rangeLen = 32;
  ++i;
  if (oob) {
    huffTab[i].val = 0;
    huffTab[i].prefixLen = huffDecoder->readBits(prefixBits);
    huffTab[i].rangeLen = jbig2HuffmanOOB;
    ++i;
  }
  huffTab[i].val = 0;
  huffTab[i].prefixLen = 0;
  huffTab[i].rangeLen = jbig2HuffmanEOT;
  huffDecoder->buildTable(huffTab, i);

  segments->append(new JBIG2CodeTable(segNum, huffTab));

  return;

 eofError:
  error(errSyntaxError, curStr->getPos(), "Unexpected EOF in JBIG2 stream");
}

Project: poppler

void JBIG2Stream::readExtensionSeg(Guint length) {
  Guint i;

  for (i = 0; i < length; ++i) {
    if (curStr->getChar() == EOF) {
      break;
    }
  }
}

Project: poppler

JBIG2Bitmap *JBIG2Stream::readGenericBitmap(GBool mmr, int w, int h,
					    int templ, GBool tpgdOn,
					    GBool useSkip, JBIG2Bitmap *skip,
					    int *atx, int *aty,
					    int mmrDataLength) {
  JBIG2Bitmap *bitmap;
  GBool ltp;
  Guint ltpCX, cx, cx0, cx1, cx2;
  int *refLine, *codingLine;
  int code1, code2, code3;
  Guchar *p0, *p1, *p2, *pp;
  Guchar *atP0, *atP1, *atP2, *atP3;
  Guint buf0, buf1, buf2;
  Guint atBuf0, atBuf1, atBuf2, atBuf3;
  int atShift0, atShift1, atShift2, atShift3;
  Guchar mask;
  int x, y, x0, x1, a0i, b1i, blackPixels, pix, i;

  bitmap = new JBIG2Bitmap(0, w, h);
  if (!bitmap->isOk()) {
    delete bitmap;
    return NULL;
  }
  bitmap->clearToZero();


  if (mmr) {

    mmrDecoder->reset();
    if (w > INT_MAX - 2) {
      error(errSyntaxError, curStr->getPos(), "Bad width in JBIG2 generic bitmap");
      w = -3;
    }
    codingLine = (int *)gmallocn(w + 1, sizeof(int));
    refLine = (int *)gmallocn(w + 2, sizeof(int));
    memset(refLine, 0, (w + 2) * sizeof(int));
    for (i = 0; i < w + 1; ++i) codingLine[i] = w;

    for (y = 0; y < h; ++y) {

      for (i = 0; codingLine[i] < w; ++i) {
	refLine[i] = codingLine[i];
      }
      refLine[i++] = w;
      refLine[i] = w;

      codingLine[0] = 0;
      a0i = 0;
      b1i = 0;
      blackPixels = 0;
      while (codingLine[a0i] < w) {
	code1 = mmrDecoder->get2DCode();
	switch (code1) {
	case twoDimPass:
          if (unlikely(b1i + 1 >= w + 2)) {
            break;
          }
          mmrAddPixels(refLine[b1i + 1], blackPixels, codingLine, &a0i, w);
          if (refLine[b1i + 1] < w) {
            b1i += 2;
          }
          break;
	case twoDimHoriz:
          code1 = code2 = 0;
          if (blackPixels) {
            do {
              code1 += code3 = mmrDecoder->getBlackCode();
            } while (code3 >= 64);
            do {
              code2 += code3 = mmrDecoder->getWhiteCode();
            } while (code3 >= 64);
          } else {
            do {
              code1 += code3 = mmrDecoder->getWhiteCode();
            } while (code3 >= 64);
            do {
              code2 += code3 = mmrDecoder->getBlackCode();
            } while (code3 >= 64);
          }
          mmrAddPixels(codingLine[a0i] + code1, blackPixels,
		       codingLine, &a0i, w);
          if (codingLine[a0i] < w) {
            mmrAddPixels(codingLine[a0i] + code2, blackPixels ^ 1,
			 codingLine, &a0i, w);
          }
          while (likely(b1i < w + 2) && refLine[b1i] <= codingLine[a0i] && refLine[b1i] < w) {
            b1i += 2;
          }
          break;
	case twoDimVertR3:
          if (unlikely(b1i >= w + 2)) {
            break;
          }
          mmrAddPixels(refLine[b1i] + 3, blackPixels, codingLine, &a0i, w);
          blackPixels ^= 1;
          if (codingLine[a0i] < w) {
            ++b1i;
            while (likely(b1i < w + 2) && refLine[b1i] <= codingLine[a0i] && refLine[b1i] < w) {
              b1i += 2;
            }
          }
          break;
	case twoDimVertR2:
          if (unlikely(b1i >= w + 2)) {
            break;
          }
          mmrAddPixels(refLine[b1i] + 2, blackPixels, codingLine, &a0i, w);
          blackPixels ^= 1;
          if (codingLine[a0i] < w) {
            ++b1i;
            while (likely(b1i < w + 2) && refLine[b1i] <= codingLine[a0i] && refLine[b1i] < w) {
              b1i += 2;
            }
          }
          break;
	case twoDimVertR1:
          if (unlikely(b1i >= w + 2)) {
            break;
          }
          mmrAddPixels(refLine[b1i] + 1, blackPixels, codingLine, &a0i, w);
          blackPixels ^= 1;
          if (codingLine[a0i] < w) {
            ++b1i;
            while (likely(b1i < w + 2) && refLine[b1i] <= codingLine[a0i] && refLine[b1i] < w) {
              b1i += 2;
            }
          }
          break;
	case twoDimVert0:
          if (unlikely(b1i >= w + 2)) {
            break;
          }
          mmrAddPixels(refLine[b1i], blackPixels, codingLine, &a0i, w);
          blackPixels ^= 1;
          if (codingLine[a0i] < w) {
            ++b1i;
            while (likely(b1i < w + 2) && refLine[b1i] <= codingLine[a0i] && refLine[b1i] < w) {
              b1i += 2;
            }
          }
          break;
	case twoDimVertL3:
          if (unlikely(b1i >= w + 2)) {
            break;
          }
          mmrAddPixelsNeg(refLine[b1i] - 3, blackPixels, codingLine, &a0i, w);
          blackPixels ^= 1;
          if (codingLine[a0i] < w) {
            if (b1i > 0) {
              --b1i;
            } else {
              ++b1i;
            }
            while (likely(b1i < w + 2) && refLine[b1i] <= codingLine[a0i] && refLine[b1i] < w) {
              b1i += 2;
            }
          }
          break;
	case twoDimVertL2:
          if (unlikely(b1i >= w + 2)) {
            break;
          }
          mmrAddPixelsNeg(refLine[b1i] - 2, blackPixels, codingLine, &a0i, w);
          blackPixels ^= 1;
          if (codingLine[a0i] < w) {
            if (b1i > 0) {
              --b1i;
            } else {
              ++b1i;
            }
            while (likely(b1i < w + 2) && refLine[b1i] <= codingLine[a0i] && refLine[b1i] < w) {
              b1i += 2;
            }
          }
          break;
	case twoDimVertL1:
          if (unlikely(b1i >= w + 2)) {
            break;
          }
          mmrAddPixelsNeg(refLine[b1i] - 1, blackPixels, codingLine, &a0i, w);
          blackPixels ^= 1;
          if (codingLine[a0i] < w) {
            if (b1i > 0) {
              --b1i;
            } else {
              ++b1i;
            }
            while (likely(b1i < w + 2) && refLine[b1i] <= codingLine[a0i] && refLine[b1i] < w) {
              b1i += 2;
            }
          }
          break;
	case EOF:
          mmrAddPixels(w, 0, codingLine, &a0i, w);
          break;
	default:
	  error(errSyntaxError, curStr->getPos(), "Illegal code in JBIG2 MMR bitmap data");
          mmrAddPixels(w, 0, codingLine, &a0i, w);
	  break;
	}
      }

      i = 0;
      while (1) {
	for (x = codingLine[i]; x < codingLine[i+1]; ++x) {
	  bitmap->setPixel(x, y);
	}
	if (codingLine[i+1] >= w || codingLine[i+2] >= w) {
	  break;
	}
	i += 2;
      }
    }

    if (mmrDataLength >= 0) {
      mmrDecoder->skipTo(mmrDataLength);
    } else {
      if (mmrDecoder->get24Bits() != 0x001001) {
	error(errSyntaxError, curStr->getPos(), "Missing EOFB in JBIG2 MMR bitmap data");
      }
    }

    gfree(refLine);
    gfree(codingLine);


  } else {
    ltpCX = 0; // make gcc happy
    if (tpgdOn) {
      switch (templ) {
      case 0:
	ltpCX = 0x3953; // 001 11001 0101 0011
	break;
      case 1:
	ltpCX = 0x079a; // 0011 11001 101 0
	break;
      case 2:
	ltpCX = 0x0e3; // 001 1100 01 1
	break;
      case 3:
	ltpCX = 0x18a; // 01100 0101 1
	break;
      }
    }

    ltp = 0;
    cx = cx0 = cx1 = cx2 = 0; // make gcc happy
    for (y = 0; y < h; ++y) {

      if (tpgdOn) {
	if (arithDecoder->decodeBit(ltpCX, genericRegionStats)) {
	  ltp = !ltp;
	}
	if (ltp) {
	  if (y > 0) {
	    bitmap->duplicateRow(y, y-1);
	  }
	  continue;
	}
      }

      switch (templ) {
      case 0:

	p2 = pp = bitmap->getDataPtr() + y * bitmap->getLineSize();
	buf2 = *p2++ << 8;
	if (y >= 1) {
	  p1 = bitmap->getDataPtr() + (y - 1) * bitmap->getLineSize();
	  buf1 = *p1++ << 8;
	  if (y >= 2) {
	    p0 = bitmap->getDataPtr() + (y - 2) * bitmap->getLineSize();
	    buf0 = *p0++ << 8;
	  } else {
	    p0 = NULL;
	    buf0 = 0;
	  }
	} else {
	  p1 = p0 = NULL;
	  buf1 = buf0 = 0;
	}

	if (atx[0] >= -8 && atx[0] <= 8 &&
	    atx[1] >= -8 && atx[1] <= 8 &&
	    atx[2] >= -8 && atx[2] <= 8 &&
	    atx[3] >= -8 && atx[3] <= 8) {
	  if (y + aty[0] >= 0 && y + aty[0] < bitmap->getHeight()) {
	    atP0 = bitmap->getDataPtr() + (y + aty[0]) * bitmap->getLineSize();
	    atBuf0 = *atP0++ << 8;
	  } else {
	    atP0 = NULL;
	    atBuf0 = 0;
	  }
	  atShift0 = 15 - atx[0];
	  if (y + aty[1] >= 0 && y + aty[1] < bitmap->getHeight()) {
	    atP1 = bitmap->getDataPtr() + (y + aty[1]) * bitmap->getLineSize();
	    atBuf1 = *atP1++ << 8;
	  } else {
	    atP1 = NULL;
	    atBuf1 = 0;
	  }
	  atShift1 = 15 - atx[1];
	  if (y + aty[2] >= 0 && y + aty[2] < bitmap->getHeight()) {
	    atP2 = bitmap->getDataPtr() + (y + aty[2]) * bitmap->getLineSize();
	    atBuf2 = *atP2++ << 8;
	  } else {
	    atP2 = NULL;
	    atBuf2 = 0;
	  }
	  atShift2 = 15 - atx[2];
	  if (y + aty[3] >= 0 && y + aty[3] < bitmap->getHeight()) {
	    atP3 = bitmap->getDataPtr() + (y + aty[3]) * bitmap->getLineSize();
	    atBuf3 = *atP3++ << 8;
	  } else {
	    atP3 = NULL;
	    atBuf3 = 0;
	  }
	  atShift3 = 15 - atx[3];

	  for (x0 = 0, x = 0; x0 < w; x0 += 8, ++pp) {
	    if (x0 + 8 < w) {
	      if (p0) {
		buf0 |= *p0++;
	      }
	      if (p1) {
		buf1 |= *p1++;
	      }
	      buf2 |= *p2++;
	      if (atP0) {
		atBuf0 |= *atP0++;
	      }
	      if (atP1) {
		atBuf1 |= *atP1++;
	      }
	      if (atP2) {
		atBuf2 |= *atP2++;
	      }
	      if (atP3) {
		atBuf3 |= *atP3++;
	      }
	    }
	    for (x1 = 0, mask = 0x80; x1 < 8 && x < w; ++x1, ++x, mask >>= 1) {

	      cx0 = (buf0 >> 14) & 0x07;
	      cx1 = (buf1 >> 13) & 0x1f;
	      cx2 = (buf2 >> 16) & 0x0f;
	      cx = (cx0 << 13) | (cx1 << 8) | (cx2 << 4) |
		   (((atBuf0 >> atShift0) & 1) << 3) |
		   (((atBuf1 >> atShift1) & 1) << 2) |
		   (((atBuf2 >> atShift2) & 1) << 1) |
		   ((atBuf3 >> atShift3) & 1);

	      if (!(useSkip && skip->getPixel(x, y))) {

		if ((pix = arithDecoder->decodeBit(cx, genericRegionStats))) {
		  *pp |= mask;
		  buf2 |= 0x8000;
		  if (aty[0] == 0) {
		    atBuf0 |= 0x8000;
		  }
		  if (aty[1] == 0) {
		    atBuf1 |= 0x8000;
		  }
		  if (aty[2] == 0) {
		    atBuf2 |= 0x8000;
		  }
		  if (aty[3] == 0) {
		    atBuf3 |= 0x8000;
		  }
		}
	      }

	      buf0 <<= 1;
	      buf1 <<= 1;
	      buf2 <<= 1;
	      atBuf0 <<= 1;
	      atBuf1 <<= 1;
	      atBuf2 <<= 1;
	      atBuf3 <<= 1;
	    }
	  }

	} else {
	  for (x0 = 0, x = 0; x0 < w; x0 += 8, ++pp) {
	    if (x0 + 8 < w) {
	      if (p0) {
		buf0 |= *p0++;
	      }
	      if (p1) {
		buf1 |= *p1++;
	      }
	      buf2 |= *p2++;
	    }
	    for (x1 = 0, mask = 0x80; x1 < 8 && x < w; ++x1, ++x, mask >>= 1) {

	      cx0 = (buf0 >> 14) & 0x07;
	      cx1 = (buf1 >> 13) & 0x1f;
	      cx2 = (buf2 >> 16) & 0x0f;
	      cx = (cx0 << 13) | (cx1 << 8) | (cx2 << 4) |
		   (bitmap->getPixel(x + atx[0], y + aty[0]) << 3) |
		   (bitmap->getPixel(x + atx[1], y + aty[1]) << 2) |
		   (bitmap->getPixel(x + atx[2], y + aty[2]) << 1) |
		   bitmap->getPixel(x + atx[3], y + aty[3]);

	      if (!(useSkip && skip->getPixel(x, y))) {

		if ((pix = arithDecoder->decodeBit(cx, genericRegionStats))) {
		  *pp |= mask;
		  buf2 |= 0x8000;
		}
	      }

	      buf0 <<= 1;
	      buf1 <<= 1;
	      buf2 <<= 1;
	    }
	  }
	}
	break;

      case 1:

	p2 = pp = bitmap->getDataPtr() + y * bitmap->getLineSize();
	buf2 = *p2++ << 8;
	if (y >= 1) {
	  p1 = bitmap->getDataPtr() + (y - 1) * bitmap->getLineSize();
	  buf1 = *p1++ << 8;
	  if (y >= 2) {
	    p0 = bitmap->getDataPtr() + (y - 2) * bitmap->getLineSize();
	    buf0 = *p0++ << 8;
	  } else {
	    p0 = NULL;
	    buf0 = 0;
	  }
	} else {
	  p1 = p0 = NULL;
	  buf1 = buf0 = 0;
	}

	if (atx[0] >= -8 && atx[0] <= 8) {
	  if (y + aty[0] >= 0) {
	    atP0 = bitmap->getDataPtr() + (y + aty[0]) * bitmap->getLineSize();
	    atBuf0 = *atP0++ << 8;
	  } else {
	    atP0 = NULL;
	    atBuf0 = 0;
	  }
	  atShift0 = 15 - atx[0];

	  for (x0 = 0, x = 0; x0 < w; x0 += 8, ++pp) {
	    if (x0 + 8 < w) {
	      if (p0) {
		buf0 |= *p0++;
	      }
	      if (p1) {
		buf1 |= *p1++;
	      }
	      buf2 |= *p2++;
	      if (atP0) {
		atBuf0 |= *atP0++;
	      }
	    }
	    for (x1 = 0, mask = 0x80; x1 < 8 && x < w; ++x1, ++x, mask >>= 1) {

	      cx0 = (buf0 >> 13) & 0x0f;
	      cx1 = (buf1 >> 13) & 0x1f;
	      cx2 = (buf2 >> 16) & 0x07;
	      cx = (cx0 << 9) | (cx1 << 4) | (cx2 << 1) |
		   ((atBuf0 >> atShift0) & 1);

	      if (!(useSkip && skip->getPixel(x, y))) {

		if ((pix = arithDecoder->decodeBit(cx, genericRegionStats))) {
		  *pp |= mask;
		  buf2 |= 0x8000;
		  if (aty[0] == 0) {
		    atBuf0 |= 0x8000;
		  }
		}
	      }

	      buf0 <<= 1;
	      buf1 <<= 1;
	      buf2 <<= 1;
	      atBuf0 <<= 1;
	    }
	  }

	} else {
	  for (x0 = 0, x = 0; x0 < w; x0 += 8, ++pp) {
	    if (x0 + 8 < w) {
	      if (p0) {
		buf0 |= *p0++;
	      }
	      if (p1) {
		buf1 |= *p1++;
	      }
	      buf2 |= *p2++;
	    }
	    for (x1 = 0, mask = 0x80; x1 < 8 && x < w; ++x1, ++x, mask >>= 1) {

	      cx0 = (buf0 >> 13) & 0x0f;
	      cx1 = (buf1 >> 13) & 0x1f;
	      cx2 = (buf2 >> 16) & 0x07;
	      cx = (cx0 << 9) | (cx1 << 4) | (cx2 << 1) |
		   bitmap->getPixel(x + atx[0], y + aty[0]);

	      if (!(useSkip && skip->getPixel(x, y))) {

		if ((pix = arithDecoder->decodeBit(cx, genericRegionStats))) {
		  *pp |= mask;
		  buf2 |= 0x8000;
		}
	      }

	      buf0 <<= 1;
	      buf1 <<= 1;
	      buf2 <<= 1;
	    }
	  }
	}
	break;

      case 2:

	p2 = pp = bitmap->getDataPtr() + y * bitmap->getLineSize();
	buf2 = *p2++ << 8;
	if (y >= 1) {
	  p1 = bitmap->getDataPtr() + (y - 1) * bitmap->getLineSize();
	  buf1 = *p1++ << 8;
	  if (y >= 2) {
	    p0 = bitmap->getDataPtr() + (y - 2) * bitmap->getLineSize();
	    buf0 = *p0++ << 8;
	  } else {
	    p0 = NULL;
	    buf0 = 0;
	  }
	} else {
	  p1 = p0 = NULL;
	  buf1 = buf0 = 0;
	}

	if (atx[0] >= -8 && atx[0] <= 8) {
	  if (y + aty[0] >= 0) {
	    atP0 = bitmap->getDataPtr() + (y + aty[0]) * bitmap->getLineSize();
	    atBuf0 = *atP0++ << 8;
	  } else {
	    atP0 = NULL;
	    atBuf0 = 0;
	  }
	  atShift0 = 15 - atx[0];

	  for (x0 = 0, x = 0; x0 < w; x0 += 8, ++pp) {
	    if (x0 + 8 < w) {
	      if (p0) {
		buf0 |= *p0++;
	      }
	      if (p1) {
		buf1 |= *p1++;
	      }
	      buf2 |= *p2++;
	      if (atP0) {
		atBuf0 |= *atP0++;
	      }
	    }
	    for (x1 = 0, mask = 0x80; x1 < 8 && x < w; ++x1, ++x, mask >>= 1) {

	      cx0 = (buf0 >> 14) & 0x07;
	      cx1 = (buf1 >> 14) & 0x0f;
	      cx2 = (buf2 >> 16) & 0x03;
	      cx = (cx0 << 7) | (cx1 << 3) | (cx2 << 1) |
		   ((atBuf0 >> atShift0) & 1);

	      if (!(useSkip && skip->getPixel(x, y))) {

		if ((pix = arithDecoder->decodeBit(cx, genericRegionStats))) {
		  *pp |= mask;
		  buf2 |= 0x8000;
		  if (aty[0] == 0) {
		    atBuf0 |= 0x8000;
		  }
		}
	      }

	      buf0 <<= 1;
	      buf1 <<= 1;
	      buf2 <<= 1;
	      atBuf0 <<= 1;
	    }
	  }

	} else {
	  for (x0 = 0, x = 0; x0 < w; x0 += 8, ++pp) {
	    if (x0 + 8 < w) {
	      if (p0) {
		buf0 |= *p0++;
	      }
	      if (p1) {
		buf1 |= *p1++;
	      }
	      buf2 |= *p2++;
	    }
	    for (x1 = 0, mask = 0x80; x1 < 8 && x < w; ++x1, ++x, mask >>= 1) {

	      cx0 = (buf0 >> 14) & 0x07;
	      cx1 = (buf1 >> 14) & 0x0f;
	      cx2 = (buf2 >> 16) & 0x03;
	      cx = (cx0 << 7) | (cx1 << 3) | (cx2 << 1) |
		   bitmap->getPixel(x + atx[0], y + aty[0]);

	      if (!(useSkip && skip->getPixel(x, y))) {

		if ((pix = arithDecoder->decodeBit(cx, genericRegionStats))) {
		  *pp |= mask;
		  buf2 |= 0x8000;
		}
	      }

	      buf0 <<= 1;
	      buf1 <<= 1;
	      buf2 <<= 1;
	    }
	  }
	}
	break;

      case 3:

	p2 = pp = bitmap->getDataPtr() + y * bitmap->getLineSize();
	buf2 = *p2++ << 8;
	if (y >= 1) {
	  p1 = bitmap->getDataPtr() + (y - 1) * bitmap->getLineSize();
	  buf1 = *p1++ << 8;
	} else {
	  p1 = NULL;
	  buf1 = 0;
	}

	if (atx[0] >= -8 && atx[0] <= 8) {
	  if (y + aty[0] >= 0) {
	    atP0 = bitmap->getDataPtr() + (y + aty[0]) * bitmap->getLineSize();
	    atBuf0 = *atP0++ << 8;
	  } else {
	    atP0 = NULL;
	    atBuf0 = 0;
	  }
	  atShift0 = 15 - atx[0];

	  for (x0 = 0, x = 0; x0 < w; x0 += 8, ++pp) {
	    if (x0 + 8 < w) {
	      if (p1) {
		buf1 |= *p1++;
	      }
	      buf2 |= *p2++;
	      if (atP0) {
		atBuf0 |= *atP0++;
	      }
	    }
	    for (x1 = 0, mask = 0x80; x1 < 8 && x < w; ++x1, ++x, mask >>= 1) {

	      cx1 = (buf1 >> 14) & 0x1f;
	      cx2 = (buf2 >> 16) & 0x0f;
	      cx = (cx1 << 5) | (cx2 << 1) |
		   ((atBuf0 >> atShift0) & 1);

	      if (!(useSkip && skip->getPixel(x, y))) {

		if ((pix = arithDecoder->decodeBit(cx, genericRegionStats))) {
		  *pp |= mask;
		  buf2 |= 0x8000;
		  if (aty[0] == 0) {
		    atBuf0 |= 0x8000;
		  }
		}
	      }

	      buf1 <<= 1;
	      buf2 <<= 1;
	      atBuf0 <<= 1;
	    }
	  }

	} else {
	  for (x0 = 0, x = 0; x0 < w; x0 += 8, ++pp) {
	    if (x0 + 8 < w) {
	      if (p1) {
		buf1 |= *p1++;
	      }
	      buf2 |= *p2++;
	    }
	    for (x1 = 0, mask = 0x80; x1 < 8 && x < w; ++x1, ++x, mask >>= 1) {

	      cx1 = (buf1 >> 14) & 0x1f;
	      cx2 = (buf2 >> 16) & 0x0f;
	      cx = (cx1 << 5) | (cx2 << 1) |
		   bitmap->getPixel(x + atx[0], y + aty[0]);

	      if (!(useSkip && skip->getPixel(x, y))) {

		if ((pix = arithDecoder->decodeBit(cx, genericRegionStats))) {
		  *pp |= mask;
		  buf2 |= 0x8000;
		}
	      }

	      buf1 <<= 1;
	      buf2 <<= 1;
	    }
	  }
	}
	break;
      }
    }
  }

  return bitmap;
}

Project: poppler

JBIG2Bitmap *JBIG2Stream::readGenericRefinementRegion(int w, int h,
						      int templ, GBool tpgrOn,
						      JBIG2Bitmap *refBitmap,
						      int refDX, int refDY,
						      int *atx, int *aty) {
  JBIG2Bitmap *bitmap;
  GBool ltp;
  Guint ltpCX, cx, cx0, cx2, cx3, cx4, tpgrCX0, tpgrCX1, tpgrCX2;
  JBIG2BitmapPtr cxPtr0 = {0};
  JBIG2BitmapPtr cxPtr1 = {0};
  JBIG2BitmapPtr cxPtr2 = {0};
  JBIG2BitmapPtr cxPtr3 = {0};
  JBIG2BitmapPtr cxPtr4 = {0};
  JBIG2BitmapPtr cxPtr5 = {0};
  JBIG2BitmapPtr cxPtr6 = {0};
  JBIG2BitmapPtr tpgrCXPtr0 = {0};
  JBIG2BitmapPtr tpgrCXPtr1 = {0};
  JBIG2BitmapPtr tpgrCXPtr2 = {0};
  int x, y, pix;

  bitmap = new JBIG2Bitmap(0, w, h);
  if (!bitmap->isOk())
  {
    delete bitmap;
    return NULL;
  }
  bitmap->clearToZero();

  if (templ) {
    ltpCX = 0x008;
  } else {
    ltpCX = 0x0010;
  }

  ltp = 0;
  for (y = 0; y < h; ++y) {

    if (templ) {

      bitmap->getPixelPtr(0, y-1, &cxPtr0);
      cx0 = bitmap->nextPixel(&cxPtr0);
      bitmap->getPixelPtr(-1, y, &cxPtr1);
      refBitmap->getPixelPtr(-refDX, y-1-refDY, &cxPtr2);
      refBitmap->getPixelPtr(-1-refDX, y-refDY, &cxPtr3);
      cx3 = refBitmap->nextPixel(&cxPtr3);
      cx3 = (cx3 << 1) | refBitmap->nextPixel(&cxPtr3);
      refBitmap->getPixelPtr(-refDX, y+1-refDY, &cxPtr4);
      cx4 = refBitmap->nextPixel(&cxPtr4);

      tpgrCX0 = tpgrCX1 = tpgrCX2 = 0; // make gcc happy
      if (tpgrOn) {
	refBitmap->getPixelPtr(-1-refDX, y-1-refDY, &tpgrCXPtr0);
	tpgrCX0 = refBitmap->nextPixel(&tpgrCXPtr0);
	tpgrCX0 = (tpgrCX0 << 1) | refBitmap->nextPixel(&tpgrCXPtr0);
	tpgrCX0 = (tpgrCX0 << 1) | refBitmap->nextPixel(&tpgrCXPtr0);
	refBitmap->getPixelPtr(-1-refDX, y-refDY, &tpgrCXPtr1);
	tpgrCX1 = refBitmap->nextPixel(&tpgrCXPtr1);
	tpgrCX1 = (tpgrCX1 << 1) | refBitmap->nextPixel(&tpgrCXPtr1);
	tpgrCX1 = (tpgrCX1 << 1) | refBitmap->nextPixel(&tpgrCXPtr1);
	refBitmap->getPixelPtr(-1-refDX, y+1-refDY, &tpgrCXPtr2);
	tpgrCX2 = refBitmap->nextPixel(&tpgrCXPtr2);
	tpgrCX2 = (tpgrCX2 << 1) | refBitmap->nextPixel(&tpgrCXPtr2);
	tpgrCX2 = (tpgrCX2 << 1) | refBitmap->nextPixel(&tpgrCXPtr2);
      } else {
	tpgrCXPtr0.p = tpgrCXPtr1.p = tpgrCXPtr2.p = NULL; // make gcc happy
	tpgrCXPtr0.shift = tpgrCXPtr1.shift = tpgrCXPtr2.shift = 0;
	tpgrCXPtr0.x = tpgrCXPtr1.x = tpgrCXPtr2.x = 0;
      }

      for (x = 0; x < w; ++x) {

	cx0 = ((cx0 << 1) | bitmap->nextPixel(&cxPtr0)) & 7;
	cx3 = ((cx3 << 1) | refBitmap->nextPixel(&cxPtr3)) & 7;
	cx4 = ((cx4 << 1) | refBitmap->nextPixel(&cxPtr4)) & 3;

	if (tpgrOn) {
	  tpgrCX0 = ((tpgrCX0 << 1) | refBitmap->nextPixel(&tpgrCXPtr0)) & 7;
	  tpgrCX1 = ((tpgrCX1 << 1) | refBitmap->nextPixel(&tpgrCXPtr1)) & 7;
	  tpgrCX2 = ((tpgrCX2 << 1) | refBitmap->nextPixel(&tpgrCXPtr2)) & 7;

	  if (arithDecoder->decodeBit(ltpCX, refinementRegionStats)) {
	    ltp = !ltp;
	  }
	  if (tpgrCX0 == 0 && tpgrCX1 == 0 && tpgrCX2 == 0) {
	    bitmap->clearPixel(x, y);
	    continue;
	  } else if (tpgrCX0 == 7 && tpgrCX1 == 7 && tpgrCX2 == 7) {
	    bitmap->setPixel(x, y);
	    continue;
	  }
	}

	cx = (cx0 << 7) | (bitmap->nextPixel(&cxPtr1) << 6) |
	     (refBitmap->nextPixel(&cxPtr2) << 5) |
	     (cx3 << 2) | cx4;

	if ((pix = arithDecoder->decodeBit(cx, refinementRegionStats))) {
	  bitmap->setPixel(x, y);
	}
      }

    } else {

      bitmap->getPixelPtr(0, y-1, &cxPtr0);
      cx0 = bitmap->nextPixel(&cxPtr0);
      bitmap->getPixelPtr(-1, y, &cxPtr1);
      refBitmap->getPixelPtr(-refDX, y-1-refDY, &cxPtr2);
      cx2 = refBitmap->nextPixel(&cxPtr2);
      refBitmap->getPixelPtr(-1-refDX, y-refDY, &cxPtr3);
      cx3 = refBitmap->nextPixel(&cxPtr3);
      cx3 = (cx3 << 1) | refBitmap->nextPixel(&cxPtr3);
      refBitmap->getPixelPtr(-1-refDX, y+1-refDY, &cxPtr4);
      cx4 = refBitmap->nextPixel(&cxPtr4);
      cx4 = (cx4 << 1) | refBitmap->nextPixel(&cxPtr4);
      bitmap->getPixelPtr(atx[0], y+aty[0], &cxPtr5);
      refBitmap->getPixelPtr(atx[1]-refDX, y+aty[1]-refDY, &cxPtr6);

      tpgrCX0 = tpgrCX1 = tpgrCX2 = 0; // make gcc happy
      if (tpgrOn) {
	refBitmap->getPixelPtr(-1-refDX, y-1-refDY, &tpgrCXPtr0);
	tpgrCX0 = refBitmap->nextPixel(&tpgrCXPtr0);
	tpgrCX0 = (tpgrCX0 << 1) | refBitmap->nextPixel(&tpgrCXPtr0);
	tpgrCX0 = (tpgrCX0 << 1) | refBitmap->nextPixel(&tpgrCXPtr0);
	refBitmap->getPixelPtr(-1-refDX, y-refDY, &tpgrCXPtr1);
	tpgrCX1 = refBitmap->nextPixel(&tpgrCXPtr1);
	tpgrCX1 = (tpgrCX1 << 1) | refBitmap->nextPixel(&tpgrCXPtr1);
	tpgrCX1 = (tpgrCX1 << 1) | refBitmap->nextPixel(&tpgrCXPtr1);
	refBitmap->getPixelPtr(-1-refDX, y+1-refDY, &tpgrCXPtr2);
	tpgrCX2 = refBitmap->nextPixel(&tpgrCXPtr2);
	tpgrCX2 = (tpgrCX2 << 1) | refBitmap->nextPixel(&tpgrCXPtr2);
	tpgrCX2 = (tpgrCX2 << 1) | refBitmap->nextPixel(&tpgrCXPtr2);
      } else {
	tpgrCXPtr0.p = tpgrCXPtr1.p = tpgrCXPtr2.p = NULL; // make gcc happy
	tpgrCXPtr0.shift = tpgrCXPtr1.shift = tpgrCXPtr2.shift = 0;
	tpgrCXPtr0.x = tpgrCXPtr1.x = tpgrCXPtr2.x = 0;
      }

      for (x = 0; x < w; ++x) {

	cx0 = ((cx0 << 1) | bitmap->nextPixel(&cxPtr0)) & 3;
	cx2 = ((cx2 << 1) | refBitmap->nextPixel(&cxPtr2)) & 3;
	cx3 = ((cx3 << 1) | refBitmap->nextPixel(&cxPtr3)) & 7;
	cx4 = ((cx4 << 1) | refBitmap->nextPixel(&cxPtr4)) & 7;

	if (tpgrOn) {
	  tpgrCX0 = ((tpgrCX0 << 1) | refBitmap->nextPixel(&tpgrCXPtr0)) & 7;
	  tpgrCX1 = ((tpgrCX1 << 1) | refBitmap->nextPixel(&tpgrCXPtr1)) & 7;
	  tpgrCX2 = ((tpgrCX2 << 1) | refBitmap->nextPixel(&tpgrCXPtr2)) & 7;

	  if (arithDecoder->decodeBit(ltpCX, refinementRegionStats)) {
	    ltp = !ltp;
	  }
	  if (tpgrCX0 == 0 && tpgrCX1 == 0 && tpgrCX2 == 0) {
	    bitmap->clearPixel(x, y);
	    continue;
	  } else if (tpgrCX0 == 7 && tpgrCX1 == 7 && tpgrCX2 == 7) {
	    bitmap->setPixel(x, y);
	    continue;
	  }
	}

	cx = (cx0 << 11) | (bitmap->nextPixel(&cxPtr1) << 10) |
	     (cx2 << 8) | (cx3 << 5) | (cx4 << 2) |
	     (bitmap->nextPixel(&cxPtr5) << 1) |
	     refBitmap->nextPixel(&cxPtr6);

	if ((pix = arithDecoder->decodeBit(cx, refinementRegionStats))) {
	  bitmap->setPixel(x, y);
	}
      }
    }
  }

  return bitmap;
}

Project: poppler

void JBIG2Stream::readGenericRegionSeg(Guint segNum, GBool imm,
				       GBool lossless, Guint length) {
  JBIG2Bitmap *bitmap;
  Guint w, h, x, y, segInfoFlags, extCombOp, rowCount;
  Guint flags, mmr, templ, tpgdOn;
  int atx[4], aty[4];

  if (!readULong(&w) || !readULong(&h) ||
      !readULong(&x) || !readULong(&y) ||
      !readUByte(&segInfoFlags)) {
    goto eofError;
  }
  extCombOp = segInfoFlags & 7;

  if (!readUByte(&flags)) {
    goto eofError;
  }
  mmr = flags & 1;
  templ = (flags >> 1) & 3;
  tpgdOn = (flags >> 3) & 1;

  if (!mmr) {
    if (templ == 0) {
      if (!readByte(&atx[0]) ||
	  !readByte(&aty[0]) ||
	  !readByte(&atx[1]) ||
	  !readByte(&aty[1]) ||
	  !readByte(&atx[2]) ||
	  !readByte(&aty[2]) ||
	  !readByte(&atx[3]) ||
	  !readByte(&aty[3])) {
	goto eofError;
      }
    } else {
      if (!readByte(&atx[0]) ||
	  !readByte(&aty[0])) {
	goto eofError;
      }
    }
  }

  if (!mmr) {
    resetGenericStats(templ, NULL);
    arithDecoder->start();
  }

  bitmap = readGenericBitmap(mmr, w, h, templ, tpgdOn, gFalse,
			     NULL, atx, aty, mmr ? length - 18 : 0);
  if (!bitmap)
    return;

  if (imm) {
    if (pageH == 0xffffffff && y + h > curPageH) {
      pageBitmap->expand(y + h, pageDefPixel);
    }
    pageBitmap->combine(bitmap, x, y, extCombOp);
    delete bitmap;

  } else {
    bitmap->setSegNum(segNum);
    segments->append(bitmap);
  }

  if (imm && length == 0xffffffff) {
    readULong(&rowCount);
  }

  return;

 eofError:
  error(errSyntaxError, curStr->getPos(), "Unexpected EOF in JBIG2 stream");
}

Project: poppler

void JBIG2Stream::readHalftoneRegionSeg(Guint segNum, GBool imm,
					GBool lossless, Guint length,
					Guint *refSegs, Guint nRefSegs) {
  JBIG2Bitmap *bitmap;
  JBIG2Segment *seg;
  JBIG2PatternDict *patternDict;
  JBIG2Bitmap *skipBitmap;
  Guint *grayImg;
  JBIG2Bitmap *grayBitmap;
  JBIG2Bitmap *patternBitmap;
  Guint w, h, x, y, segInfoFlags, extCombOp;
  Guint flags, mmr, templ, enableSkip, combOp;
  Guint gridW, gridH, stepX, stepY, patW, patH;
  int atx[4], aty[4];
  int gridX, gridY, xx, yy, bit, j;
  Guint bpp, m, n, i;

  if (!readULong(&w) || !readULong(&h) ||
      !readULong(&x) || !readULong(&y) ||
      !readUByte(&segInfoFlags)) {
    goto eofError;
  }
  extCombOp = segInfoFlags & 7;

  if (!readUByte(&flags)) {
    goto eofError;
  }
  mmr = flags & 1;
  templ = (flags >> 1) & 3;
  enableSkip = (flags >> 3) & 1;
  combOp = (flags >> 4) & 7;
  if (!readULong(&gridW) || !readULong(&gridH) ||
      !readLong(&gridX) || !readLong(&gridY) ||
      !readUWord(&stepX) || !readUWord(&stepY)) {
    goto eofError;
  }
  if (w == 0 || h == 0 || w >= INT_MAX / h) {
    error(errSyntaxError, curStr->getPos(), "Bad bitmap size in JBIG2 halftone segment");
    return;
  }
  if (gridH == 0 || gridW >= INT_MAX / gridH) {
    error(errSyntaxError, curStr->getPos(), "Bad grid size in JBIG2 halftone segment");
    return;
  }

  if (nRefSegs != 1) {
    error(errSyntaxError, curStr->getPos(), "Bad symbol dictionary reference in JBIG2 halftone segment");
    return;
  }
  seg = findSegment(refSegs[0]);
  if (seg == NULL || seg->getType() != jbig2SegPatternDict) {
    error(errSyntaxError, curStr->getPos(), "Bad symbol dictionary reference in JBIG2 halftone segment");
    return;
  }

  patternDict = (JBIG2PatternDict *)seg;
  i = patternDict->getSize();
  if (i <= 1) {
    bpp = 0;
  } else {
    --i;
    bpp = 0;
    while (i > 0) {
      ++bpp;
      i >>= 1;
    }
  }
  patW = patternDict->getBitmap(0)->getWidth();
  patH = patternDict->getBitmap(0)->getHeight();

  if (!mmr) {
    resetGenericStats(templ, NULL);
    arithDecoder->start();
  }

  bitmap = new JBIG2Bitmap(segNum, w, h);
  if (flags & 0x80) { // HDEFPIXEL
    bitmap->clearToOne();
  } else {
    bitmap->clearToZero();
  }

  skipBitmap = NULL;
  if (enableSkip) {
    skipBitmap = new JBIG2Bitmap(0, gridW, gridH);
    skipBitmap->clearToZero();
    for (m = 0; m < gridH; ++m) {
      for (n = 0; n < gridW; ++n) {
	xx = gridX + m * stepY + n * stepX;
	yy = gridY + m * stepX - n * stepY;
	if (((xx + (int)patW) >> 8) <= 0 || (xx >> 8) >= (int)w ||
	    ((yy + (int)patH) >> 8) <= 0 || (yy >> 8) >= (int)h) {
	  skipBitmap->setPixel(n, m);
	}
      }
    }
  }

  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;
  atx[2] =  2;                  aty[2] = -2;
  atx[3] = -2;                  aty[3] = -2;
  for (j = bpp - 1; j >= 0; --j) {
    grayBitmap = readGenericBitmap(mmr, gridW, gridH, templ, gFalse,
				   enableSkip, skipBitmap, atx, aty, -1);
    i = 0;
    for (m = 0; m < gridH; ++m) {
      for (n = 0; n < gridW; ++n) {
	bit = grayBitmap->getPixel(n, m) ^ (grayImg[i] & 1);
	grayImg[i] = (grayImg[i] << 1) | bit;
	++i;
      }
    }
    delete grayBitmap;
  }

  i = 0;
  for (m = 0; m < gridH; ++m) {
    xx = gridX + m * stepY;
    yy = gridY + m * stepX;
    for (n = 0; n < gridW; ++n) {
      if (!(enableSkip && skipBitmap->getPixel(n, m))) {
	patternBitmap = patternDict->getBitmap(grayImg[i]);
	if (unlikely(patternBitmap == NULL)) {
	  error(errSyntaxError, curStr->getPos(), "Bad pattern bitmap");
	  return;
	}
	bitmap->combine(patternBitmap, xx >> 8, yy >> 8, combOp);
      }
      xx += stepX;
      yy -= stepY;
      ++i;
    }
  }

  gfree(grayImg);
  if (skipBitmap) {
    delete skipBitmap;
  }

  if (imm) {
    if (pageH == 0xffffffff && y + h > curPageH) {
      pageBitmap->expand(y + h, pageDefPixel);
    }
    pageBitmap->combine(bitmap, x, y, extCombOp);
    delete bitmap;

  } else {
    segments->append(bitmap);
  }

  return;

 eofError:
  error(errSyntaxError, curStr->getPos(), "Unexpected EOF in JBIG2 stream");
}

Project: poppler

void JBIG2Stream::readPageInfoSeg(Guint length) {
  Guint xRes, yRes, flags, striping;

  if (!readULong(&pageW) || !readULong(&pageH) ||
      !readULong(&xRes) || !readULong(&yRes) ||
      !readUByte(&flags) || !readUWord(&striping)) {
    goto eofError;
  }
  pageDefPixel = (flags >> 2) & 1;
  defCombOp = (flags >> 3) & 3;

  if (pageH == 0xffffffff) {
    curPageH = striping & 0x7fff;
  } else {
    curPageH = pageH;
  }
  pageBitmap = new JBIG2Bitmap(0, pageW, curPageH);

  if (!pageBitmap->isOk()) {
    delete pageBitmap;
    pageBitmap = NULL;
    return;
  }
  
  if (pageDefPixel) {
    pageBitmap->clearToOne();
  } else {
    pageBitmap->clearToZero();
  }

  return;

 eofError:
  error(errSyntaxError, curStr->getPos(), "Unexpected EOF in JBIG2 stream");
}

Project: poppler

void JBIG2Stream::readPatternDictSeg(Guint segNum, Guint length) {
  JBIG2PatternDict *patternDict;
  JBIG2Bitmap *bitmap;
  Guint flags, patternW, patternH, grayMax, templ, mmr;
  int atx[4], aty[4];
  Guint i, x;

  if (!readUByte(&flags) ||
      !readUByte(&patternW) ||
      !readUByte(&patternH) ||
      !readULong(&grayMax)) {
    goto eofError;
  }
  templ = (flags >> 1) & 3;
  mmr = flags & 1;

  if (!mmr) {
    resetGenericStats(templ, NULL);
    arithDecoder->start();
  }

  atx[0] = -(int)patternW; aty[0] =  0;
  atx[1] = -3;             aty[1] = -1;
  atx[2] =  2;             aty[2] = -2;
  atx[3] = -2;             aty[3] = -2;
  bitmap = readGenericBitmap(mmr, (grayMax + 1) * patternW, patternH,
			     templ, gFalse, gFalse, NULL,
			     atx, aty, length - 7);

  if (!bitmap)
    return;

  patternDict = new JBIG2PatternDict(segNum, grayMax + 1);

  x = 0;
  for (i = 0; i <= grayMax && i < patternDict->getSize(); ++i) {
    patternDict->setBitmap(i, bitmap->getSlice(x, 0, patternW, patternH));
    x += patternW;
  }

  delete bitmap;

  segments->append(patternDict);

  return;

 eofError:
  error(errSyntaxError, curStr->getPos(), "Unexpected EOF in JBIG2 stream");
}

Project: poppler

void JBIG2Stream::readProfilesSeg(Guint length) {
  Guint i;

  for (i = 0; i < length; ++i) {
    if (curStr->getChar() == EOF) {
      break;
    }
  }
}