Commit message: Be paranoid, use gmallocn or gmallocn3 in all gmalloc with *
CVE: CVE-2009-3605
CWE: CWE-189
Vulnerability description: Multiple integer overflows in Poppler 0.10.5 and earlier allow remote attackers to cause a denial of service (application crash) or possibly execute arbitrary code via a crafted PDF file, related to (1) glib/poppler-page.cc; (2) ArthurOutputDev.cc, (3) CairoOutputDev.cc, (4) GfxState.cc, (5) JBIG2Stream.cc, (6) PSOutputDev.cc, and (7) SplashOutputDev.cc in poppler/; and (8) SplashBitmap.cc, (9) Splash.cc, and (10) SplashFTFont.cc in splash/.  NOTE: this may overlap CVE-2009-0791.

Project: poppler
File: ArthurOutputDev.cc

ArthurOutputDev::ArthurOutputDev(QPainter *painter):
  m_painter(painter)
{
  m_currentBrush = QBrush(Qt::SolidPattern);
  m_fontEngine = 0;
  m_font = 0;
  m_image = 0;
}

Project: poppler
File: ArthurOutputDev.cc

GBool ArthurOutputDev::beginType3Char(GfxState *state, double x, double y,
				      double dx, double dy,
				      CharCode code, Unicode *u, int uLen)
{
  return gFalse;
}

Project: poppler
File: ArthurOutputDev.cc

void ArthurOutputDev::clip(GfxState *state)
{
  m_painter->setClipPath(convertPath( state, state->getPath(), Qt::WindingFill ) );
}

Project: poppler
File: ArthurOutputDev.cc

static QPainterPath convertPath(GfxState *state, GfxPath *path, Qt::FillRule fillRule)
{
  GfxSubpath *subpath;
  double x1, y1, x2, y2, x3, y3;
  int i, j;

  QPainterPath qPath;
  qPath.setFillRule(fillRule);
  for (i = 0; i < path->getNumSubpaths(); ++i) {
    subpath = path->getSubpath(i);
    if (subpath->getNumPoints() > 0) {
      state->transform(subpath->getX(0), subpath->getY(0), &x1, &y1);
      qPath.moveTo(x1, y1);
      j = 1;
      while (j < subpath->getNumPoints()) {
	if (subpath->getCurve(j)) {
	  state->transform(subpath->getX(j), subpath->getY(j), &x1, &y1);
	  state->transform(subpath->getX(j+1), subpath->getY(j+1), &x2, &y2);
	  state->transform(subpath->getX(j+2), subpath->getY(j+2), &x3, &y3);
	  qPath.cubicTo( x1, y1, x2, y2, x3, y3);
	  j += 3;
	} else {
	  state->transform(subpath->getX(j), subpath->getY(j), &x1, &y1);
	  qPath.lineTo(x1, y1);
	  ++j;
	}
      }
      if (subpath->isClosed()) {
	qPath.closeSubpath();
      }
    }
  }
  return qPath;
}

Project: poppler
File: ArthurOutputDev.cc

void ArthurOutputDev::drawImageMask(GfxState *state, Object *ref, Stream *str,
				    int width, int height, GBool invert,
				    GBool inlineImg)
{
  qDebug() << "drawImageMask";
#if 0
  unsigned char *buffer;
  unsigned char *dest;
  cairo_surface_t *image;
  cairo_pattern_t *pattern;
  int x, y;
  ImageStream *imgStr;
  Guchar *pix;
  double *ctm;
  cairo_matrix_t matrix;
  int invert_bit;
  int row_stride;

  row_stride = (width + 3) & ~3;
  buffer = (unsigned char *) malloc (height * row_stride);
  if (buffer == NULL) {
    error(-1, "Unable to allocate memory for image.");
    return;
  }

  /* TODO: Do we want to cache these? */
  imgStr = new ImageStream(str, width, 1, 1);
  imgStr->reset();

  invert_bit = invert ? 1 : 0;

  for (y = 0; y < height; y++) {
    pix = imgStr->getLine();
    dest = buffer + y * row_stride;
    for (x = 0; x < width; x++) {

      if (pix[x] ^ invert_bit)
	*dest++ = 0;
      else
	*dest++ = 255;
    }
  }

  image = cairo_image_surface_create_for_data (buffer, CAIRO_FORMAT_A8,
					  width, height, row_stride);
  if (image == NULL)
    return;
  pattern = cairo_pattern_create_for_surface (image);
  if (pattern == NULL)
    return;

  ctm = state->getCTM();
  LOG (printf ("drawImageMask %dx%d, matrix: %f, %f, %f, %f, %f, %f\n",
	       width, height, ctm[0], ctm[1], ctm[2], ctm[3], ctm[4], ctm[5]));
  matrix.xx = ctm[0] / width;
  matrix.xy = -ctm[2] / height;
  matrix.yx = ctm[1] / width;
  matrix.yy = -ctm[3] / height;
  matrix.x0 = ctm[2] + ctm[4];
  matrix.y0 = ctm[3] + ctm[5];
  cairo_matrix_invert (&matrix);
  cairo_pattern_set_matrix (pattern, &matrix);

  cairo_pattern_set_filter (pattern, CAIRO_FILTER_BEST);
  /* FIXME: Doesn't the image mask support any colorspace? */
  cairo_set_source_rgb (cairo, fill_color.r, fill_color.g, fill_color.b);
  cairo_mask (cairo, pattern);

  cairo_pattern_destroy (pattern);
  cairo_surface_destroy (image);
  free (buffer);
  delete imgStr;
#endif
}

Project: poppler
File: ArthurOutputDev.cc

void ArthurOutputDev::drawLink(Link *link, Catalog *catalog)
{
}

Project: poppler
File: ArthurOutputDev.cc

void ArthurOutputDev::endPage() {
}

Project: poppler
File: ArthurOutputDev.cc

void ArthurOutputDev::endTextObject(GfxState *state)
{
}

Project: poppler
File: ArthurOutputDev.cc

void ArthurOutputDev::endType3Char(GfxState *state)
{
}

Project: poppler
File: ArthurOutputDev.cc

void ArthurOutputDev::eoFill(GfxState *state)
{
  m_painter->fillPath( convertPath( state, state->getPath(), Qt::OddEvenFill ), m_currentBrush );
}

Project: poppler
File: ArthurOutputDev.cc

void ArthurOutputDev::fill(GfxState *state)
{
  m_painter->fillPath( convertPath( state, state->getPath(), Qt::WindingFill ), m_currentBrush );
}

Project: poppler
File: ArthurOutputDev.cc

  GBool matches(SplashFontFileID *id) {
    return ((SplashOutFontFileID *)id)->r.num == r.num &&
           ((SplashOutFontFileID *)id)->r.gen == r.gen;
  }

Project: poppler
File: ArthurOutputDev.cc

void ArthurOutputDev::restoreState(GfxState *state)
{
  m_painter->restore();
}

Project: poppler
File: ArthurOutputDev.cc

void ArthurOutputDev::saveState(GfxState *state)
{
  m_painter->save();
}

Project: poppler
File: ArthurOutputDev.cc

void ArthurOutputDev::startDoc(XRef *xrefA) {
  xref = xrefA;
  delete m_fontEngine;
  m_fontEngine = new SplashFontEngine(
#if HAVE_T1LIB_H
  globalParams->getEnableT1lib(),
#endif
#if HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H
  globalParams->getEnableFreeType(),
#endif
  m_painter->testRenderHint(QPainter::TextAntialiasing));
}

Project: poppler
File: ArthurOutputDev.cc

void ArthurOutputDev::type3D0(GfxState *state, double wx, double wy)
{
}

Project: poppler
File: ArthurOutputDev.cc

void ArthurOutputDev::type3D1(GfxState *state, double wx, double wy,
			      double llx, double lly, double urx, double ury)
{
}

Project: poppler
File: ArthurOutputDev.cc

void ArthurOutputDev::updateCTM(GfxState *state, double m11, double m12,
				double m21, double m22,
				double m31, double m32)
{
  updateLineDash(state);
  updateLineJoin(state);
  updateLineCap(state);
  updateLineWidth(state);
}

Project: poppler
File: ArthurOutputDev.cc

void ArthurOutputDev::updateFillColor(GfxState *state)
{
  GfxRGB rgb;
  QColor brushColour = m_currentBrush.color();
  state->getFillRGB(&rgb);
  brushColour.setRgbF(colToDbl(rgb.r), colToDbl(rgb.g), colToDbl(rgb.b), brushColour.alphaF());
  m_currentBrush.setColor(brushColour);
}

Project: poppler
File: ArthurOutputDev.cc

void ArthurOutputDev::updateFillOpacity(GfxState *state)
{
  QColor brushColour= m_currentBrush.color();
  brushColour.setAlphaF(state->getFillOpacity());
  m_currentBrush.setColor(brushColour);
}

Project: poppler

void ArthurOutputDev::updateFlatness(GfxState *state)
{
}

Project: poppler

void ArthurOutputDev::updateFont(GfxState *state)
{
  GfxFont *gfxFont;
  GfxFontType fontType;
  SplashOutFontFileID *id;
  SplashFontFile *fontFile;
  SplashFontSrc *fontsrc;
  FoFiTrueType *ff;
  Ref embRef;
  Object refObj, strObj;
  GooString *fileName;
  char *tmpBuf;
  int tmpBufLen;
  Gushort *codeToGID;
  DisplayFontParam *dfp;
  double *textMat;
  double m11, m12, m21, m22, fontSize;
  SplashCoord mat[4];
  int substIdx, n;
  int faceIndex = 0;
  SplashCoord matrix[6];

  m_needFontUpdate = false;
  m_font = NULL;
  fileName = NULL;
  tmpBuf = NULL;
  substIdx = -1;

  if (!(gfxFont = state->getFont())) {
    goto err1;
  }
  fontType = gfxFont->getType();
  if (fontType == fontType3) {
    goto err1;
  }

  id = new SplashOutFontFileID(gfxFont->getID());
  if ((fontFile = m_fontEngine->getFontFile(id))) {
    delete id;

  } else {

    if (gfxFont->getEmbeddedFontID(&embRef)) {
      tmpBuf = gfxFont->readEmbFontFile(xref, &tmpBufLen);
      if (! tmpBuf)
	goto err2;
    } else if (!(fileName = gfxFont->getExtFontFile())) {

      dfp = NULL;
      if (gfxFont->getName()) {
        dfp = globalParams->getDisplayFont(gfxFont);
      }
      if (!dfp) {
	error(-1, "Couldn't find a font for '%s'",
	      gfxFont->getName() ? gfxFont->getName()->getCString()
	                         : "(unnamed)");
	goto err2;
      }
      switch (dfp->kind) {
      case displayFontT1:
	fileName = dfp->t1.fileName;
	fontType = gfxFont->isCIDFont() ? fontCIDType0 : fontType1;
	break;
      case displayFontTT:
	fileName = dfp->tt.fileName;
	fontType = gfxFont->isCIDFont() ? fontCIDType2 : fontTrueType;
	faceIndex = dfp->tt.faceIndex;
	break;
      }
    }

    fontsrc = new SplashFontSrc;
    if (fileName)
      fontsrc->setFile(fileName, gFalse);
    else
      fontsrc->setBuf(tmpBuf, tmpBufLen, gFalse);

    switch (fontType) {
    case fontType1:
      if (!(fontFile = m_fontEngine->loadType1Font(
			   id,
			   fontsrc,
			   ((Gfx8BitFont *)gfxFont)->getEncoding()))) {
	error(-1, "Couldn't create a font for '%s'",
	      gfxFont->getName() ? gfxFont->getName()->getCString()
	                         : "(unnamed)");
	goto err2;
      }
      break;
    case fontType1C:
      if (!(fontFile = m_fontEngine->loadType1CFont(
			   id,
			   fontsrc,
			   ((Gfx8BitFont *)gfxFont)->getEncoding()))) {
	error(-1, "Couldn't create a font for '%s'",
	      gfxFont->getName() ? gfxFont->getName()->getCString()
	                         : "(unnamed)");
	goto err2;
      }
      break;
    case fontType1COT:
      if (!(fontFile = m_fontEngine->loadOpenTypeT1CFont(
			   id,
			   fontsrc,
			   ((Gfx8BitFont *)gfxFont)->getEncoding()))) {
	error(-1, "Couldn't create a font for '%s'",
	      gfxFont->getName() ? gfxFont->getName()->getCString()
	                         : "(unnamed)");
	goto err2;
      }
      break;
    case fontTrueType:
    case fontTrueTypeOT:
	if (fileName)
	 ff = FoFiTrueType::load(fileName->getCString());
	else
	ff = FoFiTrueType::make(tmpBuf, tmpBufLen);
      if (ff) {
	codeToGID = ((Gfx8BitFont *)gfxFont)->getCodeToGIDMap(ff);
	n = 256;
	delete ff;
      } else {
	codeToGID = NULL;
	n = 0;
      }
      if (!(fontFile = m_fontEngine->loadTrueTypeFont(
			   id,
			   fontsrc,
			   codeToGID, n))) {
	error(-1, "Couldn't create a font for '%s'",
	      gfxFont->getName() ? gfxFont->getName()->getCString()
	                         : "(unnamed)");
	goto err2;
      }
      break;
    case fontCIDType0:
    case fontCIDType0C:
      if (!(fontFile = m_fontEngine->loadCIDFont(
			   id,
			   fontsrc))) {
	error(-1, "Couldn't create a font for '%s'",
	      gfxFont->getName() ? gfxFont->getName()->getCString()
	                         : "(unnamed)");
	goto err2;
      }
      break;
    case fontCIDType0COT:
      if (!(fontFile = m_fontEngine->loadOpenTypeCFFFont(
			   id,
			   fontsrc))) {
	error(-1, "Couldn't create a font for '%s'",
	      gfxFont->getName() ? gfxFont->getName()->getCString()
	                         : "(unnamed)");
	goto err2;
      }
      break;
    case fontCIDType2:
    case fontCIDType2OT:
      codeToGID = NULL;
      n = 0;
      if (((GfxCIDFont *)gfxFont)->getCIDToGID()) {
	n = ((GfxCIDFont *)gfxFont)->getCIDToGIDLen();
	if (n) {
	  codeToGID = (Gushort *)gmallocn(n, sizeof(Gushort));
	  memcpy(codeToGID, ((GfxCIDFont *)gfxFont)->getCIDToGID(),
		  n * sizeof(Gushort));
	}
      } else {
	if (fileName)
	  ff = FoFiTrueType::load(fileName->getCString());
	else
	  ff = FoFiTrueType::make(tmpBuf, tmpBufLen);
	if (! ff)
	  goto err2;
	codeToGID = ((GfxCIDFont *)gfxFont)->getCodeToGIDMap(ff, &n);
	delete ff;
      }
      if (!(fontFile = m_fontEngine->loadTrueTypeFont(
			   id,
			   fontsrc,
			   codeToGID, n, faceIndex))) {
	error(-1, "Couldn't create a font for '%s'",
	      gfxFont->getName() ? gfxFont->getName()->getCString()
	                         : "(unnamed)");
	goto err2;
      }
      break;
    default:
      goto err2;
    }
  }

  textMat = state->getTextMat();
  fontSize = state->getFontSize();
  m11 = textMat[0] * fontSize * state->getHorizScaling();
  m12 = textMat[1] * fontSize * state->getHorizScaling();
  m21 = textMat[2] * fontSize;
  m22 = textMat[3] * fontSize;

  {
  QMatrix painterMatrix = m_painter->worldMatrix();
  matrix[0] = painterMatrix.m11();
  matrix[1] = painterMatrix.m12();
  matrix[2] = painterMatrix.m21();
  matrix[3] = painterMatrix.m22();
  matrix[4] = painterMatrix.dx();
  matrix[5] = painterMatrix.dy();
  }

  mat[0] = m11;  mat[1] = -m12;
  mat[2] = m21;  mat[3] = -m22;
  m_font = m_fontEngine->getFont(fontFile, mat, matrix);

  return;

 err2:
  delete id;
 err1:
  return;
}

Project: poppler
File: ArthurOutputDev.cc

void ArthurOutputDev::updateLineCap(GfxState *state)
{
  switch (state->getLineCap()) {
  case 0:
    m_currentPen.setCapStyle(Qt::FlatCap);
    break;
  case 1:
    m_currentPen.setCapStyle(Qt::RoundCap);
    break;
  case 2:
    m_currentPen.setCapStyle(Qt::SquareCap);
    break;
  }
  m_painter->setPen(m_currentPen);
}

Project: poppler

void ArthurOutputDev::updateLineDash(GfxState *state)
{
}

Project: poppler
File: ArthurOutputDev.cc

void ArthurOutputDev::updateLineWidth(GfxState *state)
{
  m_currentPen.setWidthF(state->getTransformedLineWidth());
  m_painter->setPen(m_currentPen);
}

Project: poppler

void ArthurOutputDev::updateMiterLimit(GfxState *state)
{
}

Project: poppler
File: ArthurOutputDev.cc

void ArthurOutputDev::updateStrokeColor(GfxState *state)
{
  GfxRGB rgb;
  QColor penColour = m_currentPen.color();
  state->getStrokeRGB(&rgb);
  penColour.setRgbF(colToDbl(rgb.r), colToDbl(rgb.g), colToDbl(rgb.b), penColour.alphaF());
  m_currentPen.setColor(penColour);
  m_painter->setPen(m_currentPen);
}

Project: poppler
File: ArthurOutputDev.cc

  ~SplashOutFontFileID() {}

Project: poppler
File: CairoOutputDev.cc

CairoImage::CairoImage (double x1, double y1, double x2, double y2) {
  this->image = NULL;
  this->x1 = x1;
  this->y1 = y1;
  this->x2 = x2;
  this->y2 = y2;
}

Project: poppler
File: CairoOutputDev.cc

CairoImageOutputDev::CairoImageOutputDev()
{
  images = NULL;
  numImages = 0;
  size = 0;
  imgDrawCbk = NULL;
  imgDrawCbkData = NULL;
}

Project: poppler

void CairoOutputDev::beginTransparencyGroup(GfxState * /*state*/, double * /*bbox*/,
                                      GfxColorSpace * blendingColorSpace,
                                      GBool /*isolated*/, GBool knockout,
				      GBool forSoftMask) {
  /* push color space */
  ColorSpaceStack* css = new ColorSpaceStack;
  css->cs = blendingColorSpace;
  css->knockout = knockout;
  css->next = groupColorSpaceStack;
  groupColorSpaceStack = css;
  if (knockout) {
    knockoutCount++;
    if (!cairo_shape) {
      /* create a surface for tracking the shape */
      cairo_surface_t *cairo_shape_surface = cairo_surface_create_similar_clip (cairo, CAIRO_CONTENT_ALPHA);
      cairo_shape = cairo_create (cairo_shape_surface);
      cairo_surface_destroy (cairo_shape_surface);

      /* the color doesn't matter as long as it is opaque */
      cairo_set_source_rgb (cairo_shape, 0, 0, 0);
      cairo_matrix_t matrix;
      cairo_get_matrix (cairo, &matrix);
      cairo_set_matrix (cairo_shape, &matrix);
    } else {
      cairo_reference (cairo_shape);
    }
  }
  if (groupColorSpaceStack->next && groupColorSpaceStack->next->knockout) {
    /* we need to track the shape */
    cairo_push_group (cairo_shape);
  }
  if (0 && forSoftMask)
    cairo_push_group_with_content (cairo, CAIRO_CONTENT_ALPHA);
  else
    cairo_push_group (cairo);

  /* push_group has an implicit cairo_save() */
  if (knockout) {
    /*XXX: let's hope this matches the semantics needed */
    cairo_set_operator(cairo, CAIRO_OPERATOR_SOURCE);
  } else {
    cairo_set_operator(cairo, CAIRO_OPERATOR_OVER);
  }
}

Project: poppler
File: CairoOutputDev.cc

GBool CairoOutputDev::beginType3Char(GfxState *state, double x, double y,
				      double dx, double dy,
				      CharCode code, Unicode *u, int uLen) {

  cairo_save (cairo);
  double *ctm;
  cairo_matrix_t matrix;

  ctm = state->getCTM();
  matrix.xx = ctm[0];
  matrix.yx = ctm[1];
  matrix.xy = ctm[2];
  matrix.yy = ctm[3];
  matrix.x0 = ctm[4];
  matrix.y0 = ctm[5];
  /* Restore the original matrix and then transform to matrix needed for the
   * type3 font. This is ugly but seems to work. Perhaps there is a better way to do it?*/
  cairo_set_matrix(cairo, &orig_matrix);
  cairo_transform(cairo, &matrix);
  if (cairo_shape) {
    cairo_save (cairo_shape);
    cairo_set_matrix(cairo_shape, &orig_matrix);
    cairo_transform(cairo_shape, &matrix);
  }
  cairo_pattern_destroy(stroke_pattern);
  cairo_pattern_reference(fill_pattern);
  stroke_pattern = fill_pattern;
  return gFalse;
}

Project: poppler

cairo_surface_t *cairo_surface_create_similar_clip (cairo_t *cairo, cairo_content_t content)
{
  double x1, y1, x2, y2;
  int width, height;
  cairo_clip_extents (cairo, &x1, &y1, &x2, &y2);
  cairo_matrix_t matrix;
  cairo_get_matrix (cairo, &matrix);
  cairo_user_to_device(cairo, &x1, &y1);
  cairo_user_to_device(cairo, &x2, &y2);
  width = splashCeil(x2) - splashFloor(x1);
  height = splashFloor(y1) - splashCeil(y2);
  cairo_surface_t *target = cairo_get_target (cairo);
  cairo_surface_t *result;

  result = cairo_surface_create_similar (target, content, width, height);
  double x_offset, y_offset;
    cairo_surface_get_device_offset(target, &x_offset, &y_offset);
    cairo_surface_set_device_offset(result, x_offset, y_offset);

 
  return result;
}

Project: poppler
File: CairoOutputDev.cc

void CairoOutputDev::clearSoftMask(GfxState * /*state*/) {
  if (mask)
    cairo_pattern_destroy(mask);
  mask = NULL;
}

Project: poppler
File: CairoOutputDev.cc

void CairoOutputDev::clip(GfxState *state) {
  doPath (cairo, state, state->getPath());
  cairo_set_fill_rule (cairo, CAIRO_FILL_RULE_WINDING);
  cairo_clip (cairo);
  LOG (printf ("clip\n"));
  if (cairo_shape) {
    doPath (cairo_shape, state, state->getPath());
    cairo_set_fill_rule (cairo_shape, CAIRO_FILL_RULE_WINDING);
    cairo_clip (cairo_shape);
  }
}

Project: poppler
File: CairoOutputDev.cc

void CairoOutputDev::drawChar(GfxState *state, double x, double y,
			      double dx, double dy,
			      double originX, double originY,
			      CharCode code, int nBytes, Unicode *u, int uLen)
{
  if (currentFont) {
    glyphs[glyphCount].index = currentFont->getGlyph (code, u, uLen);
    glyphs[glyphCount].x = x - originX;
    glyphs[glyphCount].y = y - originY;
    glyphCount++;
  }

  if (!text)
    return;
  actualText->addChar (state, x, y, dx, dy, code, nBytes, u, uLen);
}

Project: poppler
File: CairoOutputDev.cc

void CairoImageOutputDev::drawImage(GfxState *state, Object *ref, Stream *str,
				    int width, int height, GfxImageColorMap *colorMap,
				    int *maskColors, GBool inlineImg)
{
  cairo_t *cr;
  cairo_surface_t *surface;
  double x1, y1, x2, y2;
  double *ctm;
  double mat[6];
  CairoImage *image;

  ctm = state->getCTM();
  
  mat[0] = ctm[0];
  mat[1] = ctm[1];
  mat[2] = -ctm[2];
  mat[3] = -ctm[3];
  mat[4] = ctm[2] + ctm[4];
  mat[5] = ctm[3] + ctm[5];
  x1 = mat[4];
  y1 = mat[5];
  x2 = x1 + width;
  y2 = y1 + height;

  image = new CairoImage (x1, y1, x2, y2);
  saveImage (image);

  if (imgDrawCbk && imgDrawCbk (numImages - 1, imgDrawCbkData)) {
    surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height);
    cr = cairo_create (surface);
    setCairo (cr);
    cairo_translate (cr, 0, height);
    cairo_scale (cr, width, -height);
    
    CairoOutputDev::drawImage(state, ref, str, width, height, colorMap, maskColors, inlineImg);
    image->setImage (surface);
    
    setCairo (NULL);
    cairo_surface_destroy (surface);
    cairo_destroy (cr);
  }
}

Project: poppler

void CairoOutputDev::drawImageMask(GfxState *state, Object *ref, Stream *str,
				    int width, int height, GBool invert,
				    GBool inlineImg) {

  /* FIXME: Doesn't the image mask support any colorspace? */
  cairo_set_source (cairo, fill_pattern);

  /* work around a cairo bug when scaling 1x1 surfaces */
  if (width == 1 && height == 1) {
    cairo_save (cairo);
    cairo_rectangle (cairo, 0., 0., width, height);
    cairo_fill (cairo);
    cairo_restore (cairo);
    if (cairo_shape) {
      cairo_save (cairo_shape);
      cairo_rectangle (cairo_shape, 0., 0., width, height);
      cairo_fill (cairo_shape);
      cairo_restore (cairo_shape);
    }
    return;
  }

  /* shape is 1.0 for painted areas, 0.0 for unpainted ones */

  cairo_matrix_t matrix;
  cairo_get_matrix (cairo, &matrix);
  if (!printing && prescaleImages && matrix.xy == 0.0 && matrix.yx == 0.0) {
    drawImageMaskPrescaled(state, ref, str, width, height, invert, inlineImg);
  } else {
    drawImageMaskRegular(state, ref, str, width, height, invert, inlineImg);
  }
}

Project: poppler
File: CairoOutputDev.cc

void CairoImageOutputDev::drawImageMask(GfxState *state, Object *ref, Stream *str,
					int width, int height, GBool invert,
					GBool inlineImg)
{
  cairo_t *cr;
  cairo_surface_t *surface;
  double x1, y1, x2, y2;
  double *ctm;
  double mat[6];
  CairoImage *image;

  ctm = state->getCTM();
  
  mat[0] = ctm[0];
  mat[1] = ctm[1];
  mat[2] = -ctm[2];
  mat[3] = -ctm[3];
  mat[4] = ctm[2] + ctm[4];
  mat[5] = ctm[3] + ctm[5];
  x1 = mat[4];
  y1 = mat[5];
  x2 = x1 + width;
  y2 = y1 + height;

  image = new CairoImage (x1, y1, x2, y2);
  saveImage (image);

  if (imgDrawCbk && imgDrawCbk (numImages - 1, imgDrawCbkData)) {
    surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height);
    cr = cairo_create (surface);
    setCairo (cr);
    cairo_translate (cr, 0, height);
    cairo_scale (cr, width, -height);

    CairoOutputDev::drawImageMask(state, ref, str, width, height, invert, inlineImg);
    image->setImage (surface);

    setCairo (NULL);
    cairo_surface_destroy (surface);
    cairo_destroy (cr);
  }
}

Project: poppler

void CairoOutputDev::drawImageMaskPrescaled(GfxState *state, Object *ref, Stream *str,
				    int width, int height, GBool invert,
				    GBool inlineImg) {
  unsigned char *buffer;
  cairo_surface_t *image;
  cairo_pattern_t *pattern;
  ImageStream *imgStr;
  Guchar *pix;
  cairo_matrix_t matrix;
  int invert_bit;
  int row_stride;

  /* cairo does a very poor job of scaling down images so we scale them ourselves */

  /* this scaling code is adopted from the splash image scaling code */
  cairo_get_matrix(cairo, &matrix);
#if 0
  printf("[%f %f], [%f %f], %f %f\n", matrix.xx, matrix.xy, matrix.yx, matrix.yy, matrix.x0, matrix.y0);
#endif
  /* this whole computation should be factored out */
  double xScale = matrix.xx;
  double yScale = matrix.yy;
  int tx, tx2, ty, ty2; /* the integer co-oridinates of the resulting image */
  int scaledHeight;
  int scaledWidth;
  if (xScale >= 0) {
    tx = splashRound(matrix.x0 - 0.01);
    tx2 = splashRound(matrix.x0 + xScale + 0.01) - 1;
  } else {
    tx = splashRound(matrix.x0 + 0.01) - 1;
    tx2 = splashRound(matrix.x0 + xScale - 0.01);
  }
  scaledWidth = abs(tx2 - tx) + 1;
  if (scaledWidth == 0) {
    scaledWidth = 1;
  }
  if (yScale >= 0) {
    ty = splashFloor(matrix.y0 + 0.01);
    ty2 = splashCeil(matrix.y0 + yScale - 0.01);
  } else {
    ty = splashCeil(matrix.y0 - 0.01);
    ty2 = splashFloor(matrix.y0 + yScale + 0.01);
  }
  scaledHeight = abs(ty2 - ty);
  if (scaledHeight == 0) {
    scaledHeight = 1;
  }
#if 0
  printf("xscale: %g, yscale: %g\n", xScale, yScale);
  printf("width: %d, height: %d\n", width, height);
  printf("scaledWidth: %d, scaledHeight: %d\n", scaledWidth, scaledHeight);
#endif

  /* compute the required padding */
  /* Padding is used to preserve the aspect ratio.
     We compute total_pad to make (height+total_pad)/scaledHeight as close to height/yScale as possible */
  int head_pad = 0;
  int tail_pad = 0;
  int total_pad = splashRound(height*(scaledHeight/fabs(yScale)) - height);

  /* compute the two pieces of padding */
  if (total_pad > 0) {
    float tail_error = fabs(matrix.y0 - ty);
    float head_error = fabs(ty2 - (matrix.y0 + yScale));
    float tail_fraction = tail_error/(tail_error + head_error);
    tail_pad = splashRound(total_pad*tail_fraction);
    head_pad = total_pad - tail_pad;
  } else {
    tail_pad = 0;
    head_pad = 0;
  }
  int origHeight = height;
  height += tail_pad;
  height += head_pad;
#if 0
  printf("head_pad: %d tail_pad: %d\n", head_pad, tail_pad);
  printf("origHeight: %d height: %d\n", origHeight, height);
  printf("ty: %d, ty2: %d\n", ty, ty2);
#endif

  /* TODO: Do we want to cache these? */
  imgStr = new ImageStream(str, width, 1, 1);
  imgStr->reset();

  invert_bit = invert ? 1 : 0;

  row_stride = (scaledWidth + 3) & ~3;
  buffer = (unsigned char *) malloc (scaledHeight * row_stride);
  if (buffer == NULL) {
    error(-1, "Unable to allocate memory for image.");
    return;
  }

  int yp = height / scaledHeight;
  int yq = height % scaledHeight;
  int xp = width / scaledWidth;
  int xq = width % scaledWidth;
  int yt = 0;
  int origHeight_c = origHeight;
  /* use MIN() because yp might be > origHeight because of padding */
  unsigned char *pixBuf = (unsigned char *)malloc(MIN(yp+1, origHeight)*width);
  int lastYStep = 1;
  int total = 0;
  for (int y = 0; y < scaledHeight; y++) {
    int yStep = yp;
    yt += yq;

    if (yt >= scaledHeight) {
      yt -= scaledHeight;
      ++yStep;
    }

    {
      int n = (yp > 0) ? yStep : lastYStep;
      total += n;
      if (n > 0) {
	unsigned char *p = pixBuf;
	int head_pad_count = head_pad;
	int origHeight_count = origHeight;
	int tail_pad_count = tail_pad;
	for (int i=0; i<n; i++) {
	  if (head_pad_count) {
	    head_pad_count--;
	  } else if (origHeight_count) {
	    pix = imgStr->getLine();
	    for (int j=0; j<width; j++) {
	      if (pix[j] ^ invert_bit)
		p[j] = 0;
	      else
		p[j] = 255;
	    }
	    origHeight_count--;
	    p += width;
	  } else if (tail_pad_count) {
	    tail_pad_count--;
	  } else {
	    printf("%d %d\n", n, total);
	    assert(0 && "over run\n");
	  }
	}
      }
    }

    lastYStep = yStep;
    int k1 = y;

    int xt = 0;
    int xSrc = 0;
    int x1 = k1;
    int n = yStep > 0 ? yStep : 1;
    int origN = n;

    /* compute the size of padding and pixels that will be used for this row */
    int head_pad_size = MIN(n, head_pad);
    n -= head_pad_size;
    head_pad -= MIN(head_pad_size, yStep);

    int pix_size = MIN(n, origHeight);
    n -= pix_size;
    origHeight -= MIN(pix_size, yStep);

    int tail_pad_size = MIN(n, tail_pad);
    n -= tail_pad_size;
    tail_pad -= MIN(tail_pad_size, yStep);
    if (n != 0) {
      printf("n = %d (%d %d %d)\n", n, head_pad_size, pix_size, tail_pad_size);
      assert(n == 0);
    }

    for (int x = 0; x < scaledWidth; ++x) {
      int xStep = xp;
      xt += xq;
      if (xt >= scaledWidth) {
	xt -= scaledWidth;
	++xStep;
      }
      int m = xStep > 0 ? xStep : 1;
      float pixAcc0 = 0;
      /* could m * head_pad_size * tail_pad_size  overflow? */
      if (invert_bit) {
	pixAcc0 += m * head_pad_size * tail_pad_size * 255;
      } else {
	pixAcc0 += m * head_pad_size * tail_pad_size * 0;
      }
      /* Accumulate all of the source pixels for the destination pixel */
      for (int i = 0; i < pix_size; ++i) {
	for (int j = 0; j< m; ++j) {
	  if (xSrc + i*width + j > MIN(yp + 1, origHeight_c)*width) {
	    printf("%d > %d (%d %d %d %d) (%d %d %d)\n", xSrc + i*width + j, MIN(yp + 1, origHeight_c)*width, xSrc, i , width, j, yp, origHeight_c, width);
	    printf("%d %d %d\n", head_pad_size, pix_size, tail_pad_size);
	    assert(0 && "bad access\n");
	  }
	  pixAcc0 += pixBuf[xSrc + i*width + j];
	}
      }
      buffer[y * row_stride + x] = splashFloor(pixAcc0 / (origN*m));
      xSrc += xStep;
      x1 += 1;
    }

  }
  free(pixBuf);

  image = cairo_image_surface_create_for_data (buffer, CAIRO_FORMAT_A8,
      scaledWidth, scaledHeight, row_stride);
  if (image == NULL) {
    delete imgStr;
    return;
  }
  pattern = cairo_pattern_create_for_surface (image);
  if (pattern == NULL) {
    delete imgStr;
    return;
  }

  /* we should actually be using CAIRO_FILTER_NEAREST here. However,
   * cairo doesn't yet do minifaction filtering causing scaled down
   * images with CAIRO_FILTER_NEAREST to look really bad */
  cairo_pattern_set_filter (pattern, CAIRO_FILTER_BEST);

  cairo_save (cairo);

  /* modify our current transformation so that the prescaled image
   * goes where it is supposed to */
  cairo_get_matrix(cairo, &matrix);
  cairo_scale(cairo, 1.0/matrix.xx, 1.0/matrix.yy);
  cairo_translate (cairo, tx - matrix.x0, ty2 - matrix.y0);
  if (yScale > 0)
    cairo_scale(cairo, 1, -1);

  cairo_mask (cairo, pattern);

  cairo_restore(cairo);

  if (cairo_shape) {
    cairo_save (cairo_shape);

    /* modify our current transformation so that the prescaled image
     * goes where it is supposed to */
    cairo_get_matrix(cairo_shape, &matrix);
    cairo_scale(cairo_shape, 1.0/matrix.xx, 1.0/matrix.yy);
    cairo_translate (cairo_shape, tx - matrix.x0, ty2 - matrix.y0);
    if (yScale > 0)
      cairo_scale(cairo_shape, 1, -1);

    cairo_mask (cairo_shape, pattern);

    cairo_restore(cairo_shape);
  }


  cairo_pattern_destroy (pattern);
  cairo_surface_destroy (image);
  free (buffer);
  delete imgStr;
}

Project: poppler
File: CairoOutputDev.cc

void CairoOutputDev::drawImageMaskRegular(GfxState *state, Object *ref, Stream *str,
				    int width, int height, GBool invert,
				    GBool inlineImg) {
  unsigned char *buffer;
  unsigned char *dest;
  cairo_surface_t *image;
  cairo_pattern_t *pattern;
  int x, y;
  ImageStream *imgStr;
  Guchar *pix;
  cairo_matrix_t matrix;
  int invert_bit;
  int row_stride;

  row_stride = (width + 3) & ~3;
  buffer = (unsigned char *) malloc (height * row_stride);
  if (buffer == NULL) {
    error(-1, "Unable to allocate memory for image.");
    return;
  }

  /* TODO: Do we want to cache these? */
  imgStr = new ImageStream(str, width, 1, 1);
  imgStr->reset();

  invert_bit = invert ? 1 : 0;

  for (y = 0; y < height; y++) {
    pix = imgStr->getLine();
    dest = buffer + y * row_stride;
    for (x = 0; x < width; x++) {

      if (pix[x] ^ invert_bit)
	*dest++ = 0;
      else
	*dest++ = 255;
    }
  }

  image = cairo_image_surface_create_for_data (buffer, CAIRO_FORMAT_A8,
					       width, height, row_stride);
  if (image == NULL) {
    delete imgStr;
    return;
  }
  pattern = cairo_pattern_create_for_surface (image);
  if (pattern == NULL) {
    delete imgStr;
    return;
  }

  cairo_matrix_init_translate (&matrix, 0, height);
  cairo_matrix_scale (&matrix, width, -height);

  cairo_pattern_set_matrix (pattern, &matrix);

  /* we should actually be using CAIRO_FILTER_NEAREST here. However,
   * cairo doesn't yet do minifaction filtering causing scaled down
   * images with CAIRO_FILTER_NEAREST to look really bad */
  cairo_pattern_set_filter (pattern, CAIRO_FILTER_BEST);

  cairo_mask (cairo, pattern);

  if (cairo_shape) {
#if 0
    cairo_rectangle (cairo_shape, 0., 0., width, height);
    cairo_fill (cairo_shape);
#else
    cairo_save (cairo_shape);
    /* this should draw a rectangle the size of the image
     * we use this instead of rect,fill because of the lack
     * of EXTEND_PAD */
    /* NOTE: this will multiply the edges of the image twice */
    cairo_set_source (cairo_shape, pattern);
    cairo_mask (cairo_shape, pattern);
    cairo_restore (cairo_shape);
#endif
  }


  cairo_pattern_destroy (pattern);
  cairo_surface_destroy (image);
  free (buffer);
  delete imgStr;
}

Project: poppler
File: CairoOutputDev.cc

void CairoImageOutputDev::drawMaskedImage(GfxState *state, Object *ref, Stream *str,
					  int width, int height,
					  GfxImageColorMap *colorMap,
					  Stream *maskStr,
					  int maskWidth, int maskHeight,
					  GBool maskInvert)
{
  cairo_t *cr;
  cairo_surface_t *surface;
  double x1, y1, x2, y2;
  double *ctm;
  double mat[6];
  CairoImage *image;

  ctm = state->getCTM();
  
  mat[0] = ctm[0];
  mat[1] = ctm[1];
  mat[2] = -ctm[2];
  mat[3] = -ctm[3];
  mat[4] = ctm[2] + ctm[4];
  mat[5] = ctm[3] + ctm[5];
  x1 = mat[4];
  y1 = mat[5];
  x2 = x1 + width;
  y2 = y1 + height;

  image = new CairoImage (x1, y1, x2, y2);
  saveImage (image);

  if (imgDrawCbk && imgDrawCbk (numImages - 1, imgDrawCbkData)) {
    surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height);
    cr = cairo_create (surface);
    setCairo (cr);
    cairo_translate (cr, 0, height);
    cairo_scale (cr, width, -height);
    
    CairoOutputDev::drawMaskedImage(state, ref, str, width, height, colorMap,
				    maskStr, maskWidth, maskHeight, maskInvert);
    image->setImage (surface);
    
    setCairo (NULL);
    cairo_surface_destroy (surface);
    cairo_destroy (cr);
  }
}

Project: poppler
File: CairoOutputDev.cc

void CairoImageOutputDev::drawSoftMaskedImage(GfxState *state, Object *ref, Stream *str,
					      int width, int height,
					      GfxImageColorMap *colorMap,
					      Stream *maskStr,
					      int maskWidth, int maskHeight,
					      GfxImageColorMap *maskColorMap)
{
  cairo_t *cr;
  cairo_surface_t *surface;
  double x1, y1, x2, y2;
  double *ctm;
  double mat[6];
  CairoImage *image;

  ctm = state->getCTM();
  
  mat[0] = ctm[0];
  mat[1] = ctm[1];
  mat[2] = -ctm[2];
  mat[3] = -ctm[3];
  mat[4] = ctm[2] + ctm[4];
  mat[5] = ctm[3] + ctm[5];
  x1 = mat[4];
  y1 = mat[5];
  x2 = x1 + width;
  y2 = y1 + height;

  image = new CairoImage (x1, y1, x2, y2);
  saveImage (image);

  if (imgDrawCbk && imgDrawCbk (numImages - 1, imgDrawCbkData)) {
    surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height);
    cr = cairo_create (surface);
    setCairo (cr);
    cairo_translate (cr, 0, height);
    cairo_scale (cr, width, -height);
    
    CairoOutputDev::drawSoftMaskedImage(state, ref, str, width, height, colorMap,
					maskStr, maskWidth, maskHeight, maskColorMap);
    image->setImage (surface);
    
    setCairo (NULL);
    cairo_surface_destroy (surface);
    cairo_destroy (cr);
  }
}

Project: poppler
File: CairoOutputDev.cc

void CairoOutputDev::endMarkedContent(GfxState *state)
{
  if (text)
    actualText->endMC(state);
}

Project: poppler
File: CairoOutputDev.cc

void CairoOutputDev::endPage() {
  if (text) {
    text->endPage();
    text->coalesce(gTrue, gFalse);
  }
}

Project: poppler

void CairoOutputDev::endTextObject(GfxState *state) {
  if (textClipPath) {
    cairo_append_path (cairo, textClipPath);
    cairo_clip (cairo);
    if (cairo_shape) {
      cairo_append_path (cairo_shape, textClipPath);
      cairo_clip (cairo_shape);
    }
    cairo_path_destroy (textClipPath);
    textClipPath = NULL;
  }
}

Project: poppler
File: CairoOutputDev.cc

void CairoOutputDev::endTransparencyGroup(GfxState * /*state*/) {

  if (group)
    cairo_pattern_destroy(group);
  group = cairo_pop_group (cairo);

  if (groupColorSpaceStack->next && groupColorSpaceStack->next->knockout) {
    if (shape)
      cairo_pattern_destroy(shape);
    shape = cairo_pop_group (cairo_shape);
  }
}

Project: poppler
File: CairoOutputDev.cc

void CairoOutputDev::endType3Char(GfxState *state) {
  cairo_restore (cairo);
  if (cairo_shape) {
    cairo_restore (cairo_shape);
  }
}

Project: poppler
File: CairoOutputDev.cc

void CairoOutputDev::eoClip(GfxState *state) {
  doPath (cairo, state, state->getPath());
  cairo_set_fill_rule (cairo, CAIRO_FILL_RULE_EVEN_ODD);
  cairo_clip (cairo);
  LOG (printf ("clip-eo\n"));
  if (cairo_shape) {
    doPath (cairo_shape, state, state->getPath());
    cairo_set_fill_rule (cairo_shape, CAIRO_FILL_RULE_EVEN_ODD);
    cairo_clip (cairo_shape);
  }

}

Project: poppler
File: CairoOutputDev.cc

void CairoOutputDev::eoFill(GfxState *state) {
  doPath (cairo, state, state->getPath());
  cairo_set_fill_rule (cairo, CAIRO_FILL_RULE_EVEN_ODD);
  cairo_set_source (cairo, fill_pattern);
  LOG(printf ("fill-eo\n"));
  cairo_fill (cairo);

  if (cairo_shape) {
    cairo_set_fill_rule (cairo_shape, CAIRO_FILL_RULE_EVEN_ODD);
    doPath (cairo_shape, state, state->getPath());
    cairo_fill (cairo_shape);
  }

}

Project: poppler

void CairoOutputDev::fill(GfxState *state) {
  doPath (cairo, state, state->getPath());
  cairo_set_fill_rule (cairo, CAIRO_FILL_RULE_WINDING);
  cairo_set_source (cairo, fill_pattern);
  LOG(printf ("fill\n"));
  cairo_fill (cairo);
  if (cairo_shape) {
    cairo_set_fill_rule (cairo_shape, CAIRO_FILL_RULE_WINDING);
    doPath (cairo_shape, state, state->getPath());
    cairo_fill (cairo_shape);
  }
}

Project: poppler

static uint32_t luminocity(uint32_t x)
{
  int r = (x >> 16) & 0xff;
  int g = (x >>  8) & 0xff;
  int b = (x >>  0) & 0xff;
  int y = (r*19661+g*38666+b*7209 + 32829)>>16;
  return y << 24;
}

Project: poppler

void CairoOutputDev::paintTransparencyGroup(GfxState * /*state*/, double * /*bbox*/) {
  cairo_set_source (cairo, group);

  if (!mask) {
    if (shape) {
      cairo_save (cairo);

      /* OPERATOR_SOURCE w/ a mask is defined as (src IN mask) ADD (dest OUT mask)
       * however our source has already been clipped to mask so we only need to
       * do ADD and OUT */

      /* clear the shape mask */
      cairo_set_source (cairo, shape);
      cairo_set_operator (cairo, CAIRO_OPERATOR_DEST_OUT);
      cairo_paint (cairo);

      cairo_set_operator (cairo, CAIRO_OPERATOR_ADD);
      cairo_set_source (cairo, group);
      cairo_paint (cairo);

      cairo_restore (cairo);

      cairo_pattern_destroy (shape);
      shape = NULL;
    } else {
      cairo_paint_with_alpha (cairo, fill_opacity);
    }
    cairo_status_t status = cairo_status(cairo);
    if (status)
      printf("BAD status: %s\n", cairo_status_to_string(status));
  } else {
    cairo_mask(cairo, mask);

    cairo_pattern_destroy(mask);
    mask = NULL;
  }

  popTransparencyGroup();
}

Project: poppler
File: CairoOutputDev.cc

static inline void printMatrix(cairo_matrix_t *matrix){
	printf("%f %f, %f %f (%f %f)\n", matrix->xx, matrix->yx,
			matrix->xy, matrix->yy,
			matrix->x0, matrix->y0);
}

Project: poppler
File: CairoOutputDev.cc

void CairoOutputDev::restoreState(GfxState *state) {
  LOG(printf ("restore\n"));
  cairo_restore (cairo);
  if (cairo_shape)
      cairo_restore (cairo_shape);

  /* These aren't restored by cairo_restore() since we keep them in
   * the output device. */
  updateFillColor(state);
  updateStrokeColor(state);
  updateFillOpacity(state);
  updateStrokeOpacity(state);

  MaskStack* ms = maskStack;
  if (mask)
    cairo_pattern_destroy(mask);

  mask = ms->mask;
  maskStack = ms->next;
  delete ms;
}

Project: poppler
File: CairoOutputDev.cc

void CairoImageOutputDev::saveImage(CairoImage *image)
{ 
  if (numImages >= size) {
	  size += 16;
	  images = (CairoImage **) greallocn (images, size, sizeof (CairoImage *));
  }
  images[numImages++] = image;
}

Project: poppler
File: CairoOutputDev.cc

void CairoOutputDev::saveState(GfxState *state) {
  LOG(printf ("save\n"));
  cairo_save (cairo);
  if (cairo_shape)
      cairo_save (cairo_shape);

  MaskStack *ms = new MaskStack;
  ms->mask = cairo_pattern_reference(mask);
  ms->next = maskStack;
  maskStack = ms;
}

Project: poppler

void CairoOutputDev::setCairo(cairo_t *cairo)
{
  if (this->cairo != NULL) {
    cairo_status_t status = cairo_status (this->cairo);
    if (status) {
      warning("cairo context error: %s\n", cairo_status_to_string(status));
    }
    cairo_destroy (this->cairo);
    assert(!cairo_shape);
  }
  if (cairo != NULL) {
    this->cairo = cairo_reference (cairo);
	/* save the initial matrix so that we can use it for type3 fonts. */
	cairo_get_matrix(cairo, &orig_matrix);
  } else {
    this->cairo = NULL;
    this->cairo_shape = NULL;
  }
}

Project: poppler
File: CairoOutputDev.cc

void CairoOutputDev::setDefaultCTM(double *ctm) {
  cairo_matrix_t matrix;
  matrix.xx = ctm[0];
  matrix.yx = ctm[1];
  matrix.xy = ctm[2];
  matrix.yy = ctm[3];
  matrix.x0 = ctm[4];
  matrix.y0 = ctm[5];

  cairo_transform (cairo, &matrix);
  if (cairo_shape)
      cairo_transform (cairo_shape, &matrix);

  OutputDev::setDefaultCTM(ctm);
}

Project: poppler

void CairoOutputDev::setSoftMask(GfxState * state, double * bbox, GBool alpha,
                                 Function * transferFunc, GfxColor * backdropColor) {
  cairo_pattern_destroy(mask);

  if (alpha == false) {
    /* We need to mask according to the luminocity of the group.
     * So we paint the group to an image surface convert it to a luminocity map
     * and then use that as the mask. */

    double x1, y1, x2, y2, tmp;
    cairo_clip_extents(cairo, &x1, &y1, &x2, &y2);
    cairo_user_to_device(cairo, &x1, &y1);
    cairo_user_to_device(cairo, &x2, &y2);
    if (x1 > x2) {
      tmp = x1;
      x1 = x2;
      x2 = tmp;
    }

    if (y1 > y2) {
      tmp = y1;
      y1 = y2;
      y2 = tmp;
    }

    int width = (int)(ceil(x2) - floor(x1));
    int height = (int)(ceil(y2) - floor(y1));

    cairo_surface_t *source = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height);
    cairo_t *maskCtx = cairo_create(source);

    GfxRGB backdropColorRGB;
    groupColorSpaceStack->cs->getRGB(backdropColor, &backdropColorRGB);
    /* paint the backdrop */
    cairo_set_source_rgb(maskCtx, backdropColorRGB.r / 65535.0,
			 backdropColorRGB.g / 65535.0,
			 backdropColorRGB.b / 65535.0);


    cairo_matrix_t mat;
    cairo_get_matrix(cairo, &mat);
    cairo_set_matrix(maskCtx, &mat);

    /* make the device offset of the new mask match that of the group */
    double x_offset, y_offset;
    cairo_surface_t *pats;
    cairo_pattern_get_surface(group, &pats);
    cairo_surface_get_device_offset(pats, &x_offset, &y_offset);
    cairo_surface_set_device_offset(source, x_offset, y_offset);

    /* paint the group */
    cairo_set_source(maskCtx, group);
    cairo_paint(maskCtx);

    /* XXX status = cairo_status(maskCtx); */
    cairo_destroy(maskCtx);

    /* convert to a luminocity map */
    uint32_t *source_data = (uint32_t*)cairo_image_surface_get_data(source);
    /* get stride in units of 32 bits */
    int stride = cairo_image_surface_get_stride(source)/4;
    for (int y=0; y<height; y++) {
      for (int x=0; x<width; x++) {
	source_data[y*stride + x] = luminocity(source_data[y*stride + x]);

#if 0
	here is how splash deals with the transferfunction we should deal with this
	  at some point
	if (transferFunc) {
	  transferFunc->transform(&lum, &lum2);
	} else {
	  lum2 = lum;
	}
	p[x] = (int)(lum2 * 255.0 + 0.5);
#endif

      }
    }

    /* setup the new mask pattern */
    mask = cairo_pattern_create_for_surface(source);
    cairo_matrix_t patMatrix;
    cairo_pattern_get_matrix(group, &patMatrix);
    cairo_pattern_set_matrix(mask, &patMatrix);

    cairo_surface_destroy(source);
  } else {
    mask = cairo_pattern_reference(group);
  }

  popTransparencyGroup();
}

Project: poppler
File: CairoOutputDev.cc

void CairoOutputDev::setTextPage(TextPage *text)
{
  if (this->text) 
    this->text->decRefCnt();
  if (actualText)
    delete actualText;
  if (text) {
    this->text = text;
    this->text->incRefCnt();
    actualText = new ActualText(text);
  } else {
    this->text = NULL;
    actualText = NULL;
  }
}

Project: poppler
File: CairoOutputDev.cc

static inline int splashCeil(SplashCoord x) {
  return (int)ceil(x);
}

Project: poppler
File: CairoOutputDev.cc

static inline int splashRound(SplashCoord x) {
  return (int)floor(x + 0.5);
}

Project: poppler
File: CairoOutputDev.cc

void CairoOutputDev::startDoc(XRef *xrefA, Catalog *catalogA,
			      CairoFontEngine *parentFontEngine) {
  xref = xrefA;
  catalog = catalogA;
  if (parentFontEngine) {
    fontEngine = parentFontEngine;
  } else {
    if (fontEngine) {
      delete fontEngine;
    }
    fontEngine = new CairoFontEngine(ft_lib);
    fontEngine_owner = gTrue;
  }
}

Project: poppler
File: CairoOutputDev.cc

void CairoOutputDev::startPage(int pageNum, GfxState *state) {
  /* set up some per page defaults */
  cairo_pattern_destroy(fill_pattern);
  fill_pattern = cairo_pattern_create_rgb(0., 0., 0.);

  cairo_pattern_destroy(stroke_pattern);
  stroke_pattern = cairo_pattern_create_rgb(0., 0., 0.);

  if (text)
    text->startPage(state);
}

Project: poppler
File: CairoOutputDev.cc

void CairoOutputDev::stroke(GfxState *state) {
  doPath (cairo, state, state->getPath());
  cairo_set_source (cairo, stroke_pattern);
  LOG(printf ("stroke\n"));
  cairo_stroke (cairo);
  if (cairo_shape) {
    doPath (cairo_shape, state, state->getPath());
    cairo_stroke (cairo_shape);
  }
}

Project: poppler
File: CairoOutputDev.cc

void CairoOutputDev::type3D0(GfxState *state, double wx, double wy) {
  t3_glyph_wx = wx;
  t3_glyph_wy = wy;
}

Project: poppler
File: CairoOutputDev.cc

void CairoOutputDev::type3D1(GfxState *state, double wx, double wy,
			     double llx, double lly, double urx, double ury) {
  t3_glyph_wx = wx;
  t3_glyph_wy = wy;
  t3_glyph_bbox[0] = llx;
  t3_glyph_bbox[1] = lly;
  t3_glyph_bbox[2] = urx;
  t3_glyph_bbox[3] = ury;
  t3_glyph_has_bbox = gTrue;
}

Project: poppler
File: CairoOutputDev.cc

void CairoOutputDev::updateFillColor(GfxState *state) {
  state->getFillRGB(&fill_color);

  cairo_pattern_destroy(fill_pattern);
  fill_pattern = cairo_pattern_create_rgba(fill_color.r / 65535.0,
					   fill_color.g / 65535.0,
					   fill_color.b / 65535.0,
					   fill_opacity);

  LOG(printf ("fill color: %d %d %d\n",
	      fill_color.r, fill_color.g, fill_color.b));
}

Project: poppler
File: CairoOutputDev.cc

void CairoOutputDev::updateFillOpacity(GfxState *state) {
  fill_opacity = state->getFillOpacity();

  cairo_pattern_destroy(fill_pattern);
  fill_pattern = cairo_pattern_create_rgba(fill_color.r / 65535.0,
					   fill_color.g / 65535.0,
					   fill_color.b / 65535.0,
					   fill_opacity);

  LOG(printf ("fill opacity: %f\n", fill_opacity));
}

Project: poppler

void CairoOutputDev::updateFlatness(GfxState *state) {
}

Project: poppler

void CairoOutputDev::updateFont(GfxState *state) {
  cairo_font_face_t *font_face;
  cairo_matrix_t matrix, invert_matrix;

  LOG(printf ("updateFont() font=%s\n", state->getFont()->getName()->getCString()));

  needFontUpdate = gFalse;

  if (text)
    text->updateFont(state);
  
  currentFont = fontEngine->getFont (state->getFont(), xref, catalog, printing);

  if (!currentFont)
    return;

  LOG(printf ("font matrix: %f %f %f %f\n", m11, m12, m21, m22));
  
  font_face = currentFont->getFontFace();
  cairo_set_font_face (cairo, font_face);
 
  double fontSize = state->getFontSize();
  double *m = state->getTextMat();
  /* NOTE: adjusting by a constant is hack. The correct solution
   * is probably to use user-fonts and compute the scale on a per
   * glyph basis instead of for the entire font */
  double w = currentFont->getSubstitutionCorrection(state->getFont());
  matrix.xx = m[0] * fontSize * state->getHorizScaling() * w;
  matrix.yx = m[1] * fontSize * state->getHorizScaling() * w;
  matrix.xy = -m[2] * fontSize;
  matrix.yy = -m[3] * fontSize;
  matrix.x0 = 0;
  matrix.y0 = 0;

 /* Make sure the font matrix is invertible before setting it.  cairo
  * will blow up if we give it a matrix that's not invertible, so we
  * need to check before passing it to cairo_set_font_matrix. Ignoring it
  * is likely to give better results than not rendering anything at
  * all. See #18254.
  */
  invert_matrix = matrix;
  if (cairo_matrix_invert(&invert_matrix)) {
    warning("font matrix not invertible\n");
    return;
  }

  cairo_set_font_matrix (cairo, &matrix);
}

Project: poppler
File: CairoOutputDev.cc

void CairoOutputDev::updateLineCap(GfxState *state) {
  switch (state->getLineCap()) {
  case 0:
    cairo_set_line_cap (cairo, CAIRO_LINE_CAP_BUTT);
    break;
  case 1:
    cairo_set_line_cap (cairo, CAIRO_LINE_CAP_ROUND);
    break;
  case 2:
    cairo_set_line_cap (cairo, CAIRO_LINE_CAP_SQUARE);
    break;
  }
  if (cairo_shape)
    cairo_set_line_cap (cairo_shape, cairo_get_line_cap(cairo));
}

Project: poppler
File: CairoOutputDev.cc

void CairoOutputDev::updateLineDash(GfxState *state) {
  double *dashPattern;
  int dashLength;
  double dashStart;

  state->getLineDash(&dashPattern, &dashLength, &dashStart);
  cairo_set_dash (cairo, dashPattern, dashLength, dashStart);
  if (cairo_shape)
    cairo_set_dash (cairo_shape, dashPattern, dashLength, dashStart);
}

Project: poppler
File: CairoOutputDev.cc

void CairoOutputDev::updateLineJoin(GfxState *state) {
  switch (state->getLineJoin()) {
  case 0:
    cairo_set_line_join (cairo, CAIRO_LINE_JOIN_MITER);
    break;
  case 1:
    cairo_set_line_join (cairo, CAIRO_LINE_JOIN_ROUND);
    break;
  case 2:
    cairo_set_line_join (cairo, CAIRO_LINE_JOIN_BEVEL);
    break;
  }
  if (cairo_shape)
    cairo_set_line_join (cairo_shape, cairo_get_line_join(cairo));
}

Project: poppler
File: CairoOutputDev.cc

void CairoOutputDev::updateLineWidth(GfxState *state) {
  LOG(printf ("line width: %f\n", state->getLineWidth()));
  if (state->getLineWidth() == 0.0) {
    /* find out how big pixels (device unit) are in the x and y directions
     * choose the smaller of the two as our line width */
    double x = 1.0, y = 1.0;
    cairo_device_to_user_distance(cairo, &x, &y);
    cairo_set_line_width (cairo, MIN(fabs(x),fabs(y)));
  } else {
    cairo_set_line_width (cairo, state->getLineWidth());
  }
  if (cairo_shape)
    cairo_set_line_width (cairo_shape, cairo_get_line_width (cairo));
}

Project: poppler
File: CairoOutputDev.cc

void CairoOutputDev::updateMiterLimit(GfxState *state) {
  cairo_set_miter_limit (cairo, state->getMiterLimit());
  if (cairo_shape)
    cairo_set_miter_limit (cairo_shape, state->getMiterLimit());
}

Project: poppler
File: CairoOutputDev.cc

void CairoOutputDev::updateStrokeColor(GfxState *state) {
  state->getStrokeRGB(&stroke_color);

  cairo_pattern_destroy(stroke_pattern);
  stroke_pattern = cairo_pattern_create_rgba(stroke_color.r / 65535.0,
					     stroke_color.g / 65535.0,
					     stroke_color.b / 65535.0,
					     stroke_opacity);
  
  LOG(printf ("stroke color: %d %d %d\n",
	      stroke_color.r, stroke_color.g, stroke_color.b));
}

Project: poppler
File: CairoOutputDev.cc

void CairoOutputDev::updateStrokeOpacity(GfxState *state) {
  stroke_opacity = state->getStrokeOpacity();

  cairo_pattern_destroy(stroke_pattern);
  stroke_pattern = cairo_pattern_create_rgba(stroke_color.r / 65535.0,
					     stroke_color.g / 65535.0,
					     stroke_color.b / 65535.0,
					     stroke_opacity);
  
  LOG(printf ("stroke opacity: %f\n", stroke_opacity));
}

Project: poppler
File: CairoOutputDev.cc

CairoImage::~CairoImage () {
  if (image)
    cairo_surface_destroy (image);
}

Project: poppler
File: CairoOutputDev.cc

CairoImageOutputDev::~CairoImageOutputDev()
{
  int i;

  for (i = 0; i < numImages; i++)
    delete images[i];
  gfree (images);
}

Project: poppler
File: CairoOutputDev.cc

CairoOutputDev::~CairoOutputDev() {
  if (fontEngine_owner && fontEngine) {
    delete fontEngine;
  }

  if (cairo)
    cairo_destroy (cairo);
  cairo_pattern_destroy (stroke_pattern);
  cairo_pattern_destroy (fill_pattern);
  if (group)
    cairo_pattern_destroy (group);
  if (mask)
    cairo_pattern_destroy (mask);
  if (shape)
    cairo_pattern_destroy (shape);
  if (text) 
    text->decRefCnt();
  if (actualText)
    delete actualText;  
}

Project: poppler
File: GfxState.cc

static int CMSError(int ecode, const char *msg)
{
    error(-1,const_cast<char *>(msg));
    return 1;
}

Project: poppler
File: GfxState.cc

GfxAxialShading::GfxAxialShading(double x0A, double y0A,
				 double x1A, double y1A,
				 double t0A, double t1A,
				 Function **funcsA, int nFuncsA,
				 GBool extend0A, GBool extend1A):
  GfxShading(2)
{
  int i;

  x0 = x0A;
  y0 = y0A;
  x1 = x1A;
  y1 = y1A;
  t0 = t0A;
  t1 = t1A;
  nFuncs = nFuncsA;
  for (i = 0; i < nFuncs; ++i) {
    funcs[i] = funcsA[i];
  }
  extend0 = extend0A;
  extend1 = extend1A;
}

Project: poppler
File: GfxState.cc

GfxAxialShading::GfxAxialShading(GfxAxialShading *shading):
  GfxShading(shading)
{
  int i;

  x0 = shading->x0;
  y0 = shading->y0;
  x1 = shading->x1;
  y1 = shading->y1;
  t0 = shading->t0;
  t1 = shading->t1;
  nFuncs = shading->nFuncs;
  for (i = 0; i < nFuncs; ++i) {
    funcs[i] = shading->funcs[i]->copy();
  }
  extend0 = shading->extend0;
  extend1 = shading->extend1;
}

Project: poppler
File: GfxState.cc

GfxCalGrayColorSpace::GfxCalGrayColorSpace() {
  whiteX = whiteY = whiteZ = 1;
  blackX = blackY = blackZ = 0;
  gamma = 1;
}

Project: poppler
File: GfxState.cc

GfxCalRGBColorSpace::GfxCalRGBColorSpace() {
  whiteX = whiteY = whiteZ = 1;
  blackX = blackY = blackZ = 0;
  gammaR = gammaG = gammaB = 1;
  mat[0] = 1; mat[1] = 0; mat[2] = 0;
  mat[3] = 0; mat[4] = 1; mat[5] = 0;
  mat[6] = 0; mat[7] = 0; mat[8] = 1;
}

Project: poppler
File: GfxState.cc

GfxColorSpace::GfxColorSpace() {
}

Project: poppler
File: GfxState.cc

GfxDeviceCMYKColorSpace::GfxDeviceCMYKColorSpace() {
}

Project: poppler
File: GfxState.cc

GfxDeviceGrayColorSpace::GfxDeviceGrayColorSpace() {
}

Project: poppler
File: GfxState.cc

GfxDeviceNColorSpace::GfxDeviceNColorSpace(int nCompsA,
					   GfxColorSpace *altA,
					   Function *funcA) {
  nComps = nCompsA;
  alt = altA;
  func = funcA;
  nonMarking = gFalse;
}

Project: poppler
File: GfxState.cc

GfxDeviceRGBColorSpace::GfxDeviceRGBColorSpace() {
}

Project: poppler
File: GfxState.cc

GfxFunctionShading::GfxFunctionShading(double x0A, double y0A,
				       double x1A, double y1A,
				       double *matrixA,
				       Function **funcsA, int nFuncsA):
  GfxShading(1)
{
  int i;

  x0 = x0A;
  y0 = y0A;
  x1 = x1A;
  y1 = y1A;
  for (i = 0; i < 6; ++i) {
    matrix[i] = matrixA[i];
  }
  nFuncs = nFuncsA;
  for (i = 0; i < nFuncs; ++i) {
    funcs[i] = funcsA[i];
  }
}

Project: poppler
File: GfxState.cc

GfxFunctionShading::GfxFunctionShading(GfxFunctionShading *shading):
  GfxShading(shading)
{
  int i;

  x0 = shading->x0;
  y0 = shading->y0;
  x1 = shading->x1;
  y1 = shading->y1;
  for (i = 0; i < 6; ++i) {
    matrix[i] = shading->matrix[i];
  }
  nFuncs = shading->nFuncs;
  for (i = 0; i < nFuncs; ++i) {
    funcs[i] = shading->funcs[i]->copy();
  }
}

Project: poppler
File: GfxState.cc

GfxGouraudTriangleShading::GfxGouraudTriangleShading(
			       int typeA,
			       GfxGouraudVertex *verticesA, int nVerticesA,
			       int (*trianglesA)[3], int nTrianglesA,
			       Function **funcsA, int nFuncsA):
  GfxShading(typeA)
{
  int i;

  vertices = verticesA;
  nVertices = nVerticesA;
  triangles = trianglesA;
  nTriangles = nTrianglesA;
  nFuncs = nFuncsA;
  for (i = 0; i < nFuncs; ++i) {
    funcs[i] = funcsA[i];
  }
}

Project: poppler
File: GfxState.cc

GfxGouraudTriangleShading::GfxGouraudTriangleShading(
			       GfxGouraudTriangleShading *shading):
  GfxShading(shading)
{
  int i;

  nVertices = shading->nVertices;
  vertices = (GfxGouraudVertex *)gmallocn(nVertices, sizeof(GfxGouraudVertex));
  memcpy(vertices, shading->vertices, nVertices * sizeof(GfxGouraudVertex));
  nTriangles = shading->nTriangles;
  triangles = (int (*)[3])gmallocn(nTriangles * 3, sizeof(int));
  memcpy(triangles, shading->triangles, nTriangles * 3 * sizeof(int));
  nFuncs = shading->nFuncs;
  for (i = 0; i < nFuncs; ++i) {
    funcs[i] = shading->funcs[i]->copy();
  }
}

Project: poppler
File: GfxState.cc

GfxICCBasedCache::GfxICCBasedCache()
{
  num = 0;
  gen = 0;
  colorSpace = 0;
}

Project: poppler
File: GfxState.cc

GfxImageColorMap::GfxImageColorMap(GfxImageColorMap *colorMap) {
  int n, i, k;

  colorSpace = colorMap->colorSpace->copy();
  bits = colorMap->bits;
  nComps = colorMap->nComps;
  nComps2 = colorMap->nComps2;
  colorSpace2 = NULL;
  for (k = 0; k < gfxColorMaxComps; ++k) {
    lookup[k] = NULL;
  }
  n = 1 << bits;
  if (colorSpace->getMode() == csIndexed) {
    colorSpace2 = ((GfxIndexedColorSpace *)colorSpace)->getBase();
    for (k = 0; k < nComps2; ++k) {
      lookup[k] = (GfxColorComp *)gmallocn(n, sizeof(GfxColorComp));
      memcpy(lookup[k], colorMap->lookup[k], n * sizeof(GfxColorComp));
    }
  } else if (colorSpace->getMode() == csSeparation) {
    colorSpace2 = ((GfxSeparationColorSpace *)colorSpace)->getAlt();
    for (k = 0; k < nComps2; ++k) {
      lookup[k] = (GfxColorComp *)gmallocn(n, sizeof(GfxColorComp));
      memcpy(lookup[k], colorMap->lookup[k], n * sizeof(GfxColorComp));
    }
  } else {
    for (k = 0; k < nComps; ++k) {
      lookup[k] = (GfxColorComp *)gmallocn(n, sizeof(GfxColorComp));
      memcpy(lookup[k], colorMap->lookup[k], n * sizeof(GfxColorComp));
    }
  }
  for (i = 0; i < nComps; ++i) {
    decodeLow[i] = colorMap->decodeLow[i];
    decodeRange[i] = colorMap->decodeRange[i];
  }
  ok = gTrue;
}

Project: poppler
File: GfxState.cc

GfxIndexedColorSpace::GfxIndexedColorSpace(GfxColorSpace *baseA,
					   int indexHighA) {
  base = baseA;
  indexHigh = indexHighA;
  lookup = (Guchar *)gmallocn((indexHigh + 1) * base->getNComps(),
			      sizeof(Guchar));
}

Project: poppler
File: GfxState.cc

GfxLabColorSpace::GfxLabColorSpace() {
  whiteX = whiteY = whiteZ = 1;
  blackX = blackY = blackZ = 0;
  aMin = bMin = -100;
  aMax = bMax = 100;
}

Project: poppler
File: GfxState.cc

GfxPatchMeshShading::GfxPatchMeshShading(int typeA,
					 GfxPatch *patchesA, int nPatchesA,
					 Function **funcsA, int nFuncsA):
  GfxShading(typeA)
{
  int i;

  patches = patchesA;
  nPatches = nPatchesA;
  nFuncs = nFuncsA;
  for (i = 0; i < nFuncs; ++i) {
    funcs[i] = funcsA[i];
  }
}

Project: poppler
File: GfxState.cc

GfxPatchMeshShading::GfxPatchMeshShading(GfxPatchMeshShading *shading):
  GfxShading(shading)
{
  int i;

  nPatches = shading->nPatches;
  patches = (GfxPatch *)gmallocn(nPatches, sizeof(GfxPatch));
  memcpy(patches, shading->patches, nPatches * sizeof(GfxPatch));
  nFuncs = shading->nFuncs;
  for (i = 0; i < nFuncs; ++i) {
    funcs[i] = shading->funcs[i]->copy();
  }
}

Project: poppler
File: GfxState.cc

GfxPath::GfxPath() {
  justMoved = gFalse;
  size = 16;
  n = 0;
  firstX = firstY = 0;
  subpaths = (GfxSubpath **)gmallocn(size, sizeof(GfxSubpath *));
}

Project: poppler
File: GfxState.cc

GfxPath::GfxPath(GBool justMoved1, double firstX1, double firstY1,
		 GfxSubpath **subpaths1, int n1, int size1) {
  int i;

  justMoved = justMoved1;
  firstX = firstX1;
  firstY = firstY1;
  size = size1;
  n = n1;
  subpaths = (GfxSubpath **)gmallocn(size, sizeof(GfxSubpath *));
  for (i = 0; i < n; ++i)
    subpaths[i] = subpaths1[i]->copy();
}

Project: poppler
File: GfxState.cc

GfxPattern::GfxPattern(int typeA) {
  type = typeA;
}

Project: poppler
File: GfxState.cc

GfxPatternColorSpace::GfxPatternColorSpace(GfxColorSpace *underA) {
  under = underA;
}

Project: poppler
File: GfxState.cc

GfxRadialShading::GfxRadialShading(double x0A, double y0A, double r0A,
				   double x1A, double y1A, double r1A,
				   double t0A, double t1A,
				   Function **funcsA, int nFuncsA,
				   GBool extend0A, GBool extend1A):
  GfxShading(3)
{
  int i;

  x0 = x0A;
  y0 = y0A;
  r0 = r0A;
  x1 = x1A;
  y1 = y1A;
  r1 = r1A;
  t0 = t0A;
  t1 = t1A;
  nFuncs = nFuncsA;
  for (i = 0; i < nFuncs; ++i) {
    funcs[i] = funcsA[i];
  }
  extend0 = extend0A;
  extend1 = extend1A;
}

Project: poppler
File: GfxState.cc

GfxRadialShading::GfxRadialShading(GfxRadialShading *shading):
  GfxShading(shading)
{
  int i;

  x0 = shading->x0;
  y0 = shading->y0;
  r0 = shading->r0;
  x1 = shading->x1;
  y1 = shading->y1;
  r1 = shading->r1;
  t0 = shading->t0;
  y1 = shading->t1;
  nFuncs = shading->nFuncs;
  for (i = 0; i < nFuncs; ++i) {
    funcs[i] = shading->funcs[i]->copy();
  }
  extend0 = shading->extend0;
  extend1 = shading->extend1;
}

Project: poppler
File: GfxState.cc

GfxSeparationColorSpace::GfxSeparationColorSpace(GooString *nameA,
						 GfxColorSpace *altA,
						 Function *funcA) {
  name = nameA;
  alt = altA;
  func = funcA;
  nonMarking = !name->cmp("None");
}

Project: poppler
File: GfxState.cc

GfxShading::GfxShading(int typeA) {
  type = typeA;
  colorSpace = NULL;
}

Project: poppler
File: GfxState.cc

GfxShading::GfxShading(GfxShading *shading) {
  int i;

  type = shading->type;
  colorSpace = shading->colorSpace->copy();
  for (i = 0; i < gfxColorMaxComps; ++i) {
    background.c[i] = shading->background.c[i];
  }
  hasBackground = shading->hasBackground;
  xMin = shading->xMin;
  yMin = shading->yMin;
  xMax = shading->xMax;
  yMax = shading->yMax;
  hasBBox = shading->hasBBox;
}

Project: poppler
File: GfxState.cc

GfxShadingBitBuf::GfxShadingBitBuf(Stream *strA) {
  str = strA;
  str->reset();
  bitBuf = 0;
  nBits = 0;
}

Project: poppler
File: GfxState.cc

GfxShadingPattern::GfxShadingPattern(GfxShading *shadingA, double *matrixA):
  GfxPattern(2)
{
  int i;

  shading = shadingA;
  for (i = 0; i < 6; ++i) {
    matrix[i] = matrixA[i];
  }
}

Project: poppler
File: GfxState.cc

GfxState::GfxState(double hDPIA, double vDPIA, PDFRectangle *pageBox,
		   int rotateA, GBool upsideDown) {
  double kx, ky;

  hDPI = hDPIA;
  vDPI = vDPIA;
  rotate = rotateA;
  px1 = pageBox->x1;
  py1 = pageBox->y1;
  px2 = pageBox->x2;
  py2 = pageBox->y2;
  kx = hDPI / 72.0;
  ky = vDPI / 72.0;
  if (rotate == 90) {
    ctm[0] = 0;
    ctm[1] = upsideDown ? ky : -ky;
    ctm[2] = kx;
    ctm[3] = 0;
    ctm[4] = -kx * py1;
    ctm[5] = ky * (upsideDown ? -px1 : px2);
    pageWidth = kx * (py2 - py1);
    pageHeight = ky * (px2 - px1);
  } else if (rotate == 180) {
    ctm[0] = -kx;
    ctm[1] = 0;
    ctm[2] = 0;
    ctm[3] = upsideDown ? ky : -ky;
    ctm[4] = kx * px2;
    ctm[5] = ky * (upsideDown ? -py1 : py2);
    pageWidth = kx * (px2 - px1);
    pageHeight = ky * (py2 - py1);
  } else if (rotate == 270) {
    ctm[0] = 0;
    ctm[1] = upsideDown ? -ky : ky;
    ctm[2] = -kx;
    ctm[3] = 0;
    ctm[4] = kx * py2;
    ctm[5] = ky * (upsideDown ? px2 : -px1);
    pageWidth = kx * (py2 - py1);
    pageHeight = ky * (px2 - px1);
  } else {
    ctm[0] = kx;
    ctm[1] = 0;
    ctm[2] = 0;
    ctm[3] = upsideDown ? -ky : ky;
    ctm[4] = -kx * px1;
    ctm[5] = ky * (upsideDown ? py2 : -py1);
    pageWidth = kx * (px2 - px1);
    pageHeight = ky * (py2 - py1);
  }

  fillColorSpace = new GfxDeviceGrayColorSpace();
  strokeColorSpace = new GfxDeviceGrayColorSpace();
  fillColor.c[0] = 0;
  strokeColor.c[0] = 0;
  fillPattern = NULL;
  strokePattern = NULL;
  blendMode = gfxBlendNormal;
  fillOpacity = 1;
  strokeOpacity = 1;
  fillOverprint = gFalse;
  strokeOverprint = gFalse;
  transfer[0] = transfer[1] = transfer[2] = transfer[3] = NULL;

  lineWidth = 1;
  lineDash = NULL;
  lineDashLength = 0;
  lineDashStart = 0;
  flatness = 1;
  lineJoin = 0;
  lineCap = 0;
  miterLimit = 10;
  strokeAdjust = gFalse;

  font = NULL;
  fontSize = 0;
  textMat[0] = 1; textMat[1] = 0;
  textMat[2] = 0; textMat[3] = 1;
  textMat[4] = 0; textMat[5] = 0;
  charSpace = 0;
  wordSpace = 0;
  horizScaling = 1;
  leading = 0;
  rise = 0;
  render = 0;

  path = new GfxPath();
  curX = curY = 0;
  lineX = lineY = 0;

  clipXMin = 0;
  clipYMin = 0;
  clipXMax = pageWidth;
  clipYMax = pageHeight;

  saved = NULL;
#ifdef USE_CMS
  GfxColorSpace::setupColorProfiles();
#endif
}

Project: poppler
File: GfxState.cc

GfxState::GfxState(GfxState *state) {
  int i;

  memcpy(this, state, sizeof(GfxState));
  if (fillColorSpace) {
    fillColorSpace = state->fillColorSpace->copy();
  }
  if (strokeColorSpace) {
    strokeColorSpace = state->strokeColorSpace->copy();
  }
  if (fillPattern) {
    fillPattern = state->fillPattern->copy();
  }
  if (strokePattern) {
    strokePattern = state->strokePattern->copy();
  }
  for (i = 0; i < 4; ++i) {
    if (transfer[i]) {
      transfer[i] = state->transfer[i]->copy();
    }
  }
  if (lineDashLength > 0) {
    lineDash = (double *)gmallocn(lineDashLength, sizeof(double));
    memcpy(lineDash, state->lineDash, lineDashLength * sizeof(double));
  }
  if (font)
    font->incRefCnt();

  saved = NULL;
}

Project: poppler
File: GfxState.cc

GfxSubpath::GfxSubpath(GfxSubpath *subpath) {
  size = subpath->size;
  n = subpath->n;
  x = (double *)gmallocn(size, sizeof(double));
  y = (double *)gmallocn(size, sizeof(double));
  curve = (GBool *)gmallocn(size, sizeof(GBool));
  memcpy(x, subpath->x, n * sizeof(double));
  memcpy(y, subpath->y, n * sizeof(double));
  memcpy(curve, subpath->curve, n * sizeof(GBool));
  closed = subpath->closed;
}

Project: poppler
File: GfxState.cc

GfxTilingPattern::GfxTilingPattern(int paintTypeA, int tilingTypeA,
				   double *bboxA, double xStepA, double yStepA,
				   Object *resDictA, double *matrixA,
				   Object *contentStreamA):
  GfxPattern(1)
{
  int i;

  paintType = paintTypeA;
  tilingType = tilingTypeA;
  for (i = 0; i < 4; ++i) {
    bbox[i] = bboxA[i];
  }
  xStep = xStepA;
  yStep = yStepA;
  resDictA->copy(&resDict);
  for (i = 0; i < 6; ++i) {
    matrix[i] = matrixA[i];
  }
  contentStreamA->copy(&contentStream);
}

Project: poppler
File: GfxState.cc

void GfxPath::append(GfxPath *path) {
  int i;

  if (n + path->n > size) {
    size = n + path->n;
    subpaths = (GfxSubpath **)
                 greallocn(subpaths, size, sizeof(GfxSubpath *));
  }
  for (i = 0; i < path->n; ++i) {
    subpaths[n++] = path->subpaths[i]->copy();
  }
  justMoved = gFalse;
}

Project: poppler
File: GfxState.cc

void GfxState::clearPath() {
  delete path;
  path = new GfxPath();
}

Project: poppler
File: GfxState.cc

void GfxState::clip() {
  double xMin, yMin, xMax, yMax, x, y;
  GfxSubpath *subpath;
  int i, j;

  xMin = xMax = yMin = yMax = 0; // make gcc happy
  for (i = 0; i < path->getNumSubpaths(); ++i) {
    subpath = path->getSubpath(i);
    for (j = 0; j < subpath->getNumPoints(); ++j) {
      transform(subpath->getX(j), subpath->getY(j), &x, &y);
      if (i == 0 && j == 0) {
	xMin = xMax = x;
	yMin = yMax = y;
      } else {
	if (x < xMin) {
	  xMin = x;
	} else if (x > xMax) {
	  xMax = x;
	}
	if (y < yMin) {
	  yMin = y;
	} else if (y > yMax) {
	  yMax = y;
	}
      }
    }
  }
  if (xMin > clipXMin) {
    clipXMin = xMin;
  }
  if (yMin > clipYMin) {
    clipYMin = yMin;
  }
  if (xMax < clipXMax) {
    clipXMax = xMax;
  }
  if (yMax < clipYMax) {
    clipYMax = yMax;
  }
}

Project: poppler
File: GfxState.cc

static inline GfxColorComp clip01(GfxColorComp x) {
  return (x < 0) ? 0 : (x > gfxColorComp1) ? gfxColorComp1 : x;
}

Project: poppler
File: GfxState.cc

static inline double clip01(double x) {
  return (x < 0) ? 0 : (x > 1) ? 1 : x;
}

Project: poppler

void GfxState::clipToStrokePath() {
  double xMin, yMin, xMax, yMax, x, y, t0, t1;
  GfxSubpath *subpath;
  int i, j;

  xMin = xMax = yMin = yMax = 0; // make gcc happy
  for (i = 0; i < path->getNumSubpaths(); ++i) {
    subpath = path->getSubpath(i);
    for (j = 0; j < subpath->getNumPoints(); ++j) {
      transform(subpath->getX(j), subpath->getY(j), &x, &y);
      if (i == 0 && j == 0) {
	xMin = xMax = x;
	yMin = yMax = y;
      } else {
	if (x < xMin) {
	  xMin = x;
	} else if (x > xMax) {
	  xMax = x;
	}
	if (y < yMin) {
	  yMin = y;
	} else if (y > yMax) {
	  yMax = y;
	}
      }
    }
  }

  t0 = fabs(ctm[0]);
  t1 = fabs(ctm[2]);
  if (t0 > t1) {
    xMin -= 0.5 * lineWidth * t0;
    xMax += 0.5 * lineWidth * t0;
  } else {
    xMin -= 0.5 * lineWidth * t1;
    xMax += 0.5 * lineWidth * t1;
  }
  t0 = fabs(ctm[0]);
  t1 = fabs(ctm[3]);
  if (t0 > t1) {
    yMin -= 0.5 * lineWidth * t0;
    yMax += 0.5 * lineWidth * t0;
  } else {
    yMin -= 0.5 * lineWidth * t1;
    yMax += 0.5 * lineWidth * t1;
  }

  if (xMin > clipXMin) {
    clipXMin = xMin;
  }
  if (yMin > clipYMin) {
    clipYMin = yMin;
  }
  if (xMax < clipXMax) {
    clipXMax = xMax;
  }
  if (yMax < clipYMax) {
    clipYMax = yMax;
  }
}

Project: poppler
File: GfxState.cc

void GfxSubpath::close() {
  if (x[n-1] != x[0] || y[n-1] != y[0]) {
    lineTo(x[0], y[0]);
  }
  closed = gTrue;
}

Project: poppler

void GfxState::concatCTM(double a, double b, double c,
			 double d, double e, double f) {
  double a1 = ctm[0];
  double b1 = ctm[1];
  double c1 = ctm[2];
  double d1 = ctm[3];
  int i;

  ctm[0] = a * a1 + b * c1;
  ctm[1] = a * b1 + b * d1;
  ctm[2] = c * a1 + d * c1;
  ctm[3] = c * b1 + d * d1;
  ctm[4] = e * a1 + f * c1 + ctm[4];
  ctm[5] = e * b1 + f * d1 + ctm[5];

  for (i = 0; i < 6; ++i) {
    if (ctm[i] > 1e10) {
      ctm[i] = 1e10;
    } else if (ctm[i] < -1e10) {
      ctm[i] = -1e10;
    }
  }
}

Project: poppler
File: GfxState.cc

GfxColorSpace *GfxDeviceGrayColorSpace::copy() {
  return new GfxDeviceGrayColorSpace();
}

Project: poppler
File: GfxState.cc

GfxColorSpace *GfxDeviceCMYKColorSpace::copy() {
  return new GfxDeviceCMYKColorSpace();
}

Project: poppler
File: GfxState.cc

GfxColorSpace *GfxLabColorSpace::copy() {
  GfxLabColorSpace *cs;

  cs = new GfxLabColorSpace();
  cs->whiteX = whiteX;
  cs->whiteY = whiteY;
  cs->whiteZ = whiteZ;
  cs->blackX = blackX;
  cs->blackY = blackY;
  cs->blackZ = blackZ;
  cs->aMin = aMin;
  cs->aMax = aMax;
  cs->bMin = bMin;
  cs->bMax = bMax;
  cs->kr = kr;
  cs->kg = kg;
  cs->kb = kb;
  return cs;
}

Project: poppler
File: GfxState.cc

GfxColorSpace *GfxICCBasedColorSpace::copy() {
  GfxICCBasedColorSpace *cs;
  int i;

  cs = new GfxICCBasedColorSpace(nComps, alt->copy(), &iccProfileStream);
  for (i = 0; i < 4; ++i) {
    cs->rangeMin[i] = rangeMin[i];
    cs->rangeMax[i] = rangeMax[i];
  }
#ifdef USE_CMS
  cs->transform = transform;
  if (transform != NULL) transform->ref();
  cs->lineTransform = lineTransform;
  if (lineTransform != NULL) lineTransform->ref();
#endif
  return cs;
}

Project: poppler
File: GfxState.cc

GfxColorSpace *GfxIndexedColorSpace::copy() {
  GfxIndexedColorSpace *cs;

  cs = new GfxIndexedColorSpace(base->copy(), indexHigh);
  memcpy(cs->lookup, lookup,
	 (indexHigh + 1) * base->getNComps() * sizeof(Guchar));
  return cs;
}

Project: poppler
File: GfxState.cc

GfxColorSpace *GfxSeparationColorSpace::copy() {
  return new GfxSeparationColorSpace(name->copy(), alt->copy(), func->copy());
}

Project: poppler
File: GfxState.cc

GfxColorSpace *GfxPatternColorSpace::copy() {
  return new GfxPatternColorSpace(under ? under->copy() :
				          (GfxColorSpace *)NULL);
}

Project: poppler
File: GfxState.cc

GfxPattern *GfxTilingPattern::copy() {
  return new GfxTilingPattern(paintType, tilingType, bbox, xStep, yStep,
			      &resDict, matrix, &contentStream);
}

Project: poppler
File: GfxState.cc

GfxPattern *GfxShadingPattern::copy() {
  return new GfxShadingPattern(shading->copy(), matrix);
}

Project: poppler
File: GfxState.cc

GfxShading *GfxFunctionShading::copy() {
  return new GfxFunctionShading(this);
}

Project: poppler
File: GfxState.cc

GfxShading *GfxAxialShading::copy() {
  return new GfxAxialShading(this);
}

Project: poppler
File: GfxState.cc

GfxShading *GfxRadialShading::copy() {
  return new GfxRadialShading(this);
}

Project: poppler
File: GfxState.cc

GfxShading *GfxGouraudTriangleShading::copy() {
  return new GfxGouraudTriangleShading(this);
}

Project: poppler
File: GfxState.cc

GfxShading *GfxPatchMeshShading::copy() {
  return new GfxPatchMeshShading(this);
}

Project: poppler
File: GfxState.cc

void GfxSubpath::curveTo(double x1, double y1, double x2, double y2,
			 double x3, double y3) {
  if (n+3 > size) {
    size += 16;
    x = (double *)greallocn(x, size, sizeof(double));
    y = (double *)greallocn(y, size, sizeof(double));
    curve = (GBool *)greallocn(curve, size, sizeof(GBool));
  }
  x[n] = x1;
  y[n] = y1;
  x[n+1] = x2;
  y[n+1] = y2;
  x[n+2] = x3;
  y[n+2] = y3;
  curve[n] = curve[n+1] = gTrue;
  curve[n+2] = gFalse;
  n += 3;
}

Project: poppler
File: GfxState.cc

unsigned int GfxColorSpace::getCMSColorSpaceType(icColorSpaceSignature cs)
{
    switch (cs) {
    case icSigXYZData:
      return PT_XYZ;
      break;
    case icSigLabData:
      return PT_Lab;
      break;
    case icSigLuvData:
      return PT_YUV;
      break;
    case icSigYCbCrData:
      return PT_YCbCr;
      break;
    case icSigYxyData:
      return PT_Yxy;
      break;
    case icSigRgbData:
      return PT_RGB;
      break;
    case icSigGrayData:
      return PT_GRAY;
      break;
    case icSigHsvData:
      return PT_HSV;
      break;
    case icSigHlsData:
      return PT_HLS;
      break;
    case icSigCmykData:
      return PT_CMYK;
      break;
    case icSigCmyData:
      return PT_CMY;
      break;
    case icSig2colorData:
    case icSig3colorData:
    case icSig4colorData:
    case icSig5colorData:
    case icSig6colorData:
    case icSig7colorData:
    case icSig8colorData:
    case icSig9colorData:
    case icSig10colorData:
    case icSig11colorData:
    case icSig12colorData:
    case icSig13colorData:
    case icSig14colorData:
    case icSig15colorData:
    default:
      break;
    }
    return PT_RGB;
}

Project: poppler
File: GfxState.cc

unsigned int GfxColorSpace::getCMSNChannels(icColorSpaceSignature cs)
{
    switch (cs) {
    case icSigXYZData:
    case icSigLuvData:
    case icSigLabData:
    case icSigYCbCrData:
    case icSigYxyData:
    case icSigRgbData:
    case icSigHsvData:
    case icSigHlsData:
    case icSigCmyData:
    case icSig3colorData:
      return 3;
      break;
    case icSigGrayData:
      return 1;
      break;
    case icSigCmykData:
    case icSig4colorData:
      return 4;
      break;
    case icSig2colorData:
      return 2;
      break;
    case icSig5colorData:
      return 5;
      break;
    case icSig6colorData:
      return 6;
      break;
    case icSig7colorData:
      return 7;
      break;
    case icSig8colorData:
      return 8;
      break;
    case icSig9colorData:
      return 9;
      break;
    case icSig10colorData:
      return 10;
      break;
    case icSig11colorData:
      return 11;
      break;
    case icSig12colorData:
      return 12;
      break;
    case icSig13colorData:
      return 13;
      break;
    case icSig14colorData:
      return 14;
      break;
    case icSig15colorData:
      return 15;
    default:
      break;
    }
    return 3;
}

Project: poppler
File: GfxState.cc

void GfxDeviceGrayColorSpace::getCMYK(GfxColor *color, GfxCMYK *cmyk) {
  cmyk->c = cmyk->m = cmyk->y = 0;
  cmyk->k = clip01(gfxColorComp1 - color->c[0]);
}

Project: poppler
File: GfxState.cc

void GfxDeviceRGBColorSpace::getCMYK(GfxColor *color, GfxCMYK *cmyk) {
  GfxColorComp c, m, y, k;

  c = clip01(gfxColorComp1 - color->c[0]);
  m = clip01(gfxColorComp1 - color->c[1]);
  y = clip01(gfxColorComp1 - color->c[2]);
  k = c;
  if (m < k) {
    k = m;
  }
  if (y < k) {
    k = y;
  }
  cmyk->c = c - k;
  cmyk->m = m - k;
  cmyk->y = y - k;
  cmyk->k = k;
}

Project: poppler
File: GfxState.cc

void GfxCalRGBColorSpace::getCMYK(GfxColor *color, GfxCMYK *cmyk) {
  GfxRGB rgb;
  GfxColorComp c, m, y, k;

#ifdef USE_CMS
  if (XYZ2DisplayTransform != NULL && displayPixelType == PT_CMYK) {
    double in[gfxColorMaxComps];
    Guchar out[gfxColorMaxComps];
    double X, Y, Z;
    
    getXYZ(color,&X,&Y,&Z);
    in[0] = clip01(X);
    in[1] = clip01(Y);
    in[2] = clip01(Z);
    XYZ2DisplayTransform->doTransform(in,out,1);
    cmyk->c = byteToCol(out[0]);
    cmyk->m = byteToCol(out[1]);
    cmyk->y = byteToCol(out[2]);
    cmyk->k = byteToCol(out[3]);
    return;
  }
#endif
  getRGB(color, &rgb);
  c = clip01(gfxColorComp1 - rgb.r);
  m = clip01(gfxColorComp1 - rgb.g);
  y = clip01(gfxColorComp1 - rgb.b);
  k = c;
  if (m < k) {
    k = m;
  }
  if (y < k) {
    k = y;
  }
  cmyk->c = c - k;
  cmyk->m = m - k;
  cmyk->y = y - k;
  cmyk->k = k;
}

Project: poppler
File: GfxState.cc

void GfxDeviceCMYKColorSpace::getCMYK(GfxColor *color, GfxCMYK *cmyk) {
  cmyk->c = clip01(color->c[0]);
  cmyk->m = clip01(color->c[1]);
  cmyk->y = clip01(color->c[2]);
  cmyk->k = clip01(color->c[3]);
}

Project: poppler
File: GfxState.cc

void GfxLabColorSpace::getCMYK(GfxColor *color, GfxCMYK *cmyk) {
  GfxRGB rgb;
  GfxColorComp c, m, y, k;

#ifdef USE_CMS
  if (XYZ2DisplayTransform != NULL && displayPixelType == PT_CMYK) {
    double in[gfxColorMaxComps];
    Guchar out[gfxColorMaxComps];
    
    getXYZ(color, &in[0], &in[1], &in[2]);
    XYZ2DisplayTransform->doTransform(in,out,1);
    cmyk->c = byteToCol(out[0]);
    cmyk->m = byteToCol(out[1]);
    cmyk->y = byteToCol(out[2]);
    cmyk->k = byteToCol(out[3]);
    return;
  }
#endif
  getRGB(color, &rgb);
  c = clip01(gfxColorComp1 - rgb.r);
  m = clip01(gfxColorComp1 - rgb.g);
  y = clip01(gfxColorComp1 - rgb.b);
  k = c;
  if (m < k) {
    k = m;
  }
  if (y < k) {
    k = y;
  }
  cmyk->c = c - k;
  cmyk->m = m - k;
  cmyk->y = y - k;
  cmyk->k = k;
}

Project: poppler
File: GfxState.cc

void GfxICCBasedColorSpace::getCMYK(GfxColor *color, GfxCMYK *cmyk) {
#ifdef USE_CMS
  if (transform != NULL && displayPixelType == PT_CMYK) {
    Guchar in[gfxColorMaxComps];
    Guchar out[gfxColorMaxComps];
    
    for (int i = 0;i < nComps;i++) {
	in[i] = colToByte(color->c[i]);
    }
    transform->doTransform(in,out,1);
    cmyk->c = byteToCol(out[0]);
    cmyk->m = byteToCol(out[1]);
    cmyk->y = byteToCol(out[2]);
    cmyk->k = byteToCol(out[3]);
  } else {
    GfxRGB rgb;
    GfxColorComp c, m, y, k;

    getRGB(color,&rgb);
    c = clip01(gfxColorComp1 - rgb.r);
    m = clip01(gfxColorComp1 - rgb.g);
    y = clip01(gfxColorComp1 - rgb.b);
    k = c;
    if (m < k) {
      k = m;
    }
    if (y < k) {
      k = y;
    }
    cmyk->c = c - k;
    cmyk->m = m - k;
    cmyk->y = y - k;
    cmyk->k = k;
  }
#else
  alt->getCMYK(color, cmyk);
#endif
}

Project: poppler
File: GfxState.cc

void GfxIndexedColorSpace::getCMYK(GfxColor *color, GfxCMYK *cmyk) {
  GfxColor color2;

  base->getCMYK(mapColorToBase(color, &color2), cmyk);
}

Project: poppler
File: GfxState.cc

void GfxSeparationColorSpace::getCMYK(GfxColor *color, GfxCMYK *cmyk) {
  double x;
  double c[gfxColorMaxComps];
  GfxColor color2;
  int i;

  x = colToDbl(color->c[0]);
  func->transform(&x, c);
  for (i = 0; i < alt->getNComps(); ++i) {
    color2.c[i] = dblToCol(c[i]);
  }
  alt->getCMYK(&color2, cmyk);
}

Project: poppler
File: GfxState.cc

void GfxDeviceNColorSpace::getCMYK(GfxColor *color, GfxCMYK *cmyk) {
  double x[gfxColorMaxComps], c[gfxColorMaxComps];
  GfxColor color2;
  int i;

  for (i = 0; i < nComps; ++i) {
    x[i] = colToDbl(color->c[i]);
  }
  func->transform(x, c);
  for (i = 0; i < alt->getNComps(); ++i) {
    color2.c[i] = dblToCol(c[i]);
  }
  alt->getCMYK(&color2, cmyk);
}

Project: poppler
File: GfxState.cc

void GfxImageColorMap::getCMYK(Guchar *x, GfxCMYK *cmyk) {
  GfxColor color;
  int i;

  if (colorSpace2) {
    for (i = 0; i < nComps2; ++i) {
      color.c[i] = lookup[i][x[0]];
    }
    colorSpace2->getCMYK(&color, cmyk);
  } else {
    for (i = 0; i < nComps; ++i) {
      color.c[i] = lookup[i][x[i]];
    }
    colorSpace->getCMYK(&color, cmyk);
  }
}

Project: poppler

void GfxFunctionShading::getColor(double x, double y, GfxColor *color) {
  double in[2], out[gfxColorMaxComps];
  int i;

  for (i = 0; i < gfxColorMaxComps; ++i) {
    out[i] = 0;
  }
  in[0] = x;
  in[1] = y;
  for (i = 0; i < nFuncs; ++i) {
    funcs[i]->transform(in, &out[i]);
  }
  for (i = 0; i < gfxColorMaxComps; ++i) {
    color->c[i] = dblToCol(out[i]);
  }
}

Project: poppler

void GfxAxialShading::getColor(double t, GfxColor *color) {
  double out[gfxColorMaxComps];
  int i;

  for (i = 0; i < gfxColorMaxComps; ++i) {
    out[i] = 0;
  }
  for (i = 0; i < nFuncs; ++i) {
    funcs[i]->transform(&t, &out[i]);
  }
  for (i = 0; i < gfxColorMaxComps; ++i) {
    color->c[i] = dblToCol(out[i]);
  }
}

Project: poppler

void GfxRadialShading::getColor(double t, GfxColor *color) {
  double out[gfxColorMaxComps];
  int i;

  for (i = 0; i < gfxColorMaxComps; ++i) {
    out[i] = 0;
  }
  for (i = 0; i < nFuncs; ++i) {
    funcs[i]->transform(&t, &out[i]);
  }
  for (i = 0; i < gfxColorMaxComps; ++i) {
    color->c[i] = dblToCol(out[i]);
  }
}

Project: poppler
File: GfxState.cc

void GfxImageColorMap::getColor(Guchar *x, GfxColor *color) {
  int maxPixel, i;

  maxPixel = (1 << bits) - 1;
  for (i = 0; i < nComps; ++i) {
    color->c[i] = dblToCol(decodeLow[i] + (x[i] * decodeRange[i]) / maxPixel);
  }
}

Project: poppler
File: GfxState.cc

char *GfxColorSpace::getColorSpaceModeName(int idx) {
  return gfxColorSpaceModeNames[idx];
}

Project: poppler
File: GfxState.cc

void GfxDeviceGrayColorSpace::getDefaultColor(GfxColor *color) {
  color->c[0] = 0;
}

Project: poppler
File: GfxState.cc

void GfxCalGrayColorSpace::getDefaultColor(GfxColor *color) {
  color->c[0] = 0;
}

Project: poppler
File: GfxState.cc

void GfxDeviceRGBColorSpace::getDefaultColor(GfxColor *color) {
  color->c[0] = 0;
  color->c[1] = 0;
  color->c[2] = 0;
}

Project: poppler
File: GfxState.cc

void GfxCalRGBColorSpace::getDefaultColor(GfxColor *color) {
  color->c[0] = 0;
  color->c[1] = 0;
  color->c[2] = 0;
}

Project: poppler
File: GfxState.cc

void GfxDeviceCMYKColorSpace::getDefaultColor(GfxColor *color) {
  color->c[0] = 0;
  color->c[1] = 0;
  color->c[2] = 0;
  color->c[3] = gfxColorComp1;
}

Project: poppler
File: GfxState.cc

void GfxICCBasedColorSpace::getDefaultColor(GfxColor *color) {
  int i;

  for (i = 0; i < nComps; ++i) {
    if (rangeMin[i] > 0) {
      color->c[i] = dblToCol(rangeMin[i]);
    } else if (rangeMax[i] < 0) {
      color->c[i] = dblToCol(rangeMax[i]);
    } else {
      color->c[i] = 0;
    }
  }
}

Project: poppler
File: GfxState.cc

void GfxIndexedColorSpace::getDefaultColor(GfxColor *color) {
  color->c[0] = 0;
}

Project: poppler
File: GfxState.cc

void GfxSeparationColorSpace::getDefaultColor(GfxColor *color) {
  color->c[0] = gfxColorComp1;
}

Project: poppler
File: GfxState.cc

void GfxDeviceNColorSpace::getDefaultColor(GfxColor *color) {
  int i;

  for (i = 0; i < nComps; ++i) {
    color->c[i] = gfxColorComp1;
  }
}

Project: poppler
File: GfxState.cc

void GfxPatternColorSpace::getDefaultColor(GfxColor *color) {
  color->c[0]=0;
}

Project: poppler
File: GfxState.cc

void GfxColorSpace::getDefaultRanges(double *decodeLow, double *decodeRange,
				     int maxImgPixel) {
  int i;

  for (i = 0; i < getNComps(); ++i) {
    decodeLow[i] = 0;
    decodeRange[i] = 1;
  }
}

Project: poppler
File: GfxState.cc

void GfxLabColorSpace::getDefaultRanges(double *decodeLow, double *decodeRange,
					int maxImgPixel) {
  decodeLow[0] = 0;
  decodeRange[0] = 100;
  decodeLow[1] = aMin;
  decodeRange[1] = aMax - aMin;
  decodeLow[2] = bMin;
  decodeRange[2] = bMax - bMin;
}

Project: poppler

void GfxICCBasedColorSpace::getDefaultRanges(double *decodeLow,
					     double *decodeRange,
					     int maxImgPixel) {
  alt->getDefaultRanges(decodeLow, decodeRange, maxImgPixel);

#if 0
  int i;

  for (i = 0; i < nComps; ++i) {
    decodeLow[i] = rangeMin[i];
    decodeRange[i] = rangeMax[i] - rangeMin[i];
  }
#endif
}

Project: poppler
File: GfxState.cc

void GfxIndexedColorSpace::getDefaultRanges(double *decodeLow,
					    double *decodeRange,
					    int maxImgPixel) {
  decodeLow[0] = 0;
  decodeRange[0] = maxImgPixel;
}

Project: poppler
File: GfxState.cc

void GfxState::getFontTransMat(double *m11, double *m12,
			       double *m21, double *m22) {
  *m11 = (textMat[0] * ctm[0] + textMat[1] * ctm[2]) * fontSize;
  *m12 = (textMat[0] * ctm[1] + textMat[1] * ctm[3]) * fontSize;
  *m21 = (textMat[2] * ctm[0] + textMat[3] * ctm[2]) * fontSize;
  *m22 = (textMat[2] * ctm[1] + textMat[3] * ctm[3]) * fontSize;
}

Project: poppler
File: GfxState.cc

void GfxDeviceGrayColorSpace::getGray(GfxColor *color, GfxGray *gray) {
  *gray = clip01(color->c[0]);
}

Project: poppler
File: GfxState.cc

void GfxCalGrayColorSpace::getGray(GfxColor *color, GfxGray *gray) {
  GfxRGB rgb;

#ifdef USE_CMS
  if (XYZ2DisplayTransform != NULL && displayPixelType == PT_GRAY) {
    Guchar out[gfxColorMaxComps];
    double in[gfxColorMaxComps];
    double X, Y, Z;
    
    getXYZ(color,&X,&Y,&Z);
    in[0] = clip01(X);
    in[1] = clip01(Y);
    in[2] = clip01(Z);
    XYZ2DisplayTransform->doTransform(in,out,1);
    *gray = byteToCol(out[0]);
    return;
  }
#endif
  getRGB(color, &rgb);
  *gray = clip01((GfxColorComp)(0.299 * rgb.r +
				0.587 * rgb.g +
				0.114 * rgb.b + 0.5));
}

Project: poppler
File: GfxState.cc

void GfxDeviceRGBColorSpace::getGray(GfxColor *color, GfxGray *gray) {
  *gray = clip01((GfxColorComp)(0.3 * color->c[0] +
		 0.59 * color->c[1] +
		 0.11 * color->c[2] + 0.5));
}

Project: poppler
File: GfxState.cc

void GfxCalRGBColorSpace::getGray(GfxColor *color, GfxGray *gray) {
  GfxRGB rgb;

#ifdef USE_CMS
  if (XYZ2DisplayTransform != NULL && displayPixelType == PT_GRAY) {
    Guchar out[gfxColorMaxComps];
    double in[gfxColorMaxComps];
    double X, Y, Z;
    
    getXYZ(color,&X,&Y,&Z);
    in[0] = clip01(X);
    in[1] = clip01(Y);
    in[2] = clip01(Z);
    XYZ2DisplayTransform->doTransform(in,out,1);
    *gray = byteToCol(out[0]);
    return;
  }
#endif
  getRGB(color, &rgb);
  *gray = clip01((GfxColorComp)(0.299 * rgb.r +
				0.587 * rgb.g +
				0.114 * rgb.b + 0.5));
}

Project: poppler
File: GfxState.cc

void GfxDeviceCMYKColorSpace::getGray(GfxColor *color, GfxGray *gray) {
  *gray = clip01((GfxColorComp)(gfxColorComp1 - color->c[3]
				- 0.3  * color->c[0]
				- 0.59 * color->c[1]
				- 0.11 * color->c[2] + 0.5));
}

Project: poppler
File: GfxState.cc

void GfxLabColorSpace::getGray(GfxColor *color, GfxGray *gray) {
  GfxRGB rgb;

#ifdef USE_CMS
  if (XYZ2DisplayTransform != NULL && displayPixelType == PT_GRAY) {
    Guchar out[gfxColorMaxComps];
    double in[gfxColorMaxComps];
    
    getXYZ(color, &in[0], &in[1], &in[2]);
    XYZ2DisplayTransform->doTransform(in,out,1);
    *gray = byteToCol(out[0]);
    return;
  }
#endif
  getRGB(color, &rgb);
  *gray = clip01((GfxColorComp)(0.299 * rgb.r +
				0.587 * rgb.g +
				0.114 * rgb.b + 0.5));
}

Project: poppler
File: GfxState.cc

void GfxICCBasedColorSpace::getGray(GfxColor *color, GfxGray *gray) {
#ifdef USE_CMS
  if (transform != 0 && displayPixelType == PT_GRAY) {
    Guchar in[gfxColorMaxComps];
    Guchar out[gfxColorMaxComps];
    
    for (int i = 0;i < nComps;i++) {
	in[i] = colToByte(color->c[i]);
    }
    transform->doTransform(in,out,1);
    *gray = byteToCol(out[0]);
  } else {
    GfxRGB rgb;
    getRGB(color,&rgb);
    *gray = clip01((GfxColorComp)(0.3 * rgb.r +
		   0.59 * rgb.g +
		   0.11 * rgb.b + 0.5));
  }
#else
  alt->getGray(color, gray);
#endif
}

Project: poppler
File: GfxState.cc

void GfxIndexedColorSpace::getGray(GfxColor *color, GfxGray *gray) {
  GfxColor color2;

  base->getGray(mapColorToBase(color, &color2), gray);
}

Project: poppler
File: GfxState.cc

void GfxSeparationColorSpace::getGray(GfxColor *color, GfxGray *gray) {
  double x;
  double c[gfxColorMaxComps];
  GfxColor color2;
  int i;

  x = colToDbl(color->c[0]);
  func->transform(&x, c);
  for (i = 0; i < alt->getNComps(); ++i) {
    color2.c[i] = dblToCol(c[i]);
  }
  alt->getGray(&color2, gray);
}

Project: poppler
File: GfxState.cc

void GfxDeviceNColorSpace::getGray(GfxColor *color, GfxGray *gray) {
  double x[gfxColorMaxComps], c[gfxColorMaxComps];
  GfxColor color2;
  int i;

  for (i = 0; i < nComps; ++i) {
    x[i] = colToDbl(color->c[i]);
  }
  func->transform(x, c);
  for (i = 0; i < alt->getNComps(); ++i) {
    color2.c[i] = dblToCol(c[i]);
  }
  alt->getGray(&color2, gray);
}

Project: poppler
File: GfxState.cc

void GfxPatternColorSpace::getGray(GfxColor *color, GfxGray *gray) {
  *gray = 0;
}

Project: poppler
File: GfxState.cc

void GfxImageColorMap::getGray(Guchar *x, GfxGray *gray) {
  GfxColor color;
  int i;

  if (colorSpace2) {
    for (i = 0; i < nComps2; ++i) {
      color.c[i] = lookup[i][x[0]];
    }
    colorSpace2->getGray(&color, gray);
  } else {
    for (i = 0; i < nComps; ++i) {
      color.c[i] = lookup[i][x[i]];
    }
    colorSpace->getGray(&color, gray);
  }
}

Project: poppler
File: GfxState.cc

void GfxColorSpace::getGrayLine(Guchar *in, unsigned char *out, int length) {
  int i, j, n;
  GfxColor color;
  GfxGray gray;

  n = getNComps();
  for (i = 0; i < length; i++) {
    
    for (j = 0; j < n; j++)
      color.c[j] = in[i * n + j] * 256;

    getGray (&color, &gray);
    out[i] = colToByte(gray);
  }
}

Project: poppler
File: GfxState.cc

void GfxDeviceGrayColorSpace::getGrayLine(Guchar *in, Guchar *out, int length) {
  memcpy (out, in, length);
}

Project: poppler
File: GfxState.cc

void GfxDeviceRGBColorSpace::getGrayLine(Guchar *in, Guchar *out, int length) {
  int i;

  for (i = 0; i < length; i++) {
    out[i] = 
      (in[i * 3 + 0] * 19595 + 
       in[i * 3 + 1] * 38469 + 
       in[i * 3 + 2] * 7472) / 65536;
  }
}

Project: poppler
File: GfxState.cc

int GfxColorSpace::getNumColorSpaceModes() {
  return nGfxColorSpaceModes;
}

Project: poppler
File: GfxState.cc

void GfxDeviceGrayColorSpace::getRGB(GfxColor *color, GfxRGB *rgb) {
  rgb->r = rgb->g = rgb->b = clip01(color->c[0]);
}

Project: poppler

void GfxCalGrayColorSpace::getRGB(GfxColor *color, GfxRGB *rgb) {
  double X, Y, Z;
  double r, g, b;

  getXYZ(color,&X,&Y,&Z);
#ifdef USE_CMS
  if (XYZ2DisplayTransform != NULL && displayPixelType == PT_RGB) {
    Guchar out[gfxColorMaxComps];
    double in[gfxColorMaxComps];
    
    in[0] = clip01(X);
    in[1] = clip01(Y);
    in[2] = clip01(Z);
    XYZ2DisplayTransform->doTransform(in,out,1);
    rgb->r = byteToCol(out[0]);
    rgb->g = byteToCol(out[1]);
    rgb->b = byteToCol(out[2]);
    return;
  }
#endif
  X *= whiteX;
  Y *= whiteY;
  Z *= whiteZ;
  r = xyzrgb[0][0] * X + xyzrgb[0][1] * Y + xyzrgb[0][2] * Z;
  g = xyzrgb[1][0] * X + xyzrgb[1][1] * Y + xyzrgb[1][2] * Z;
  b = xyzrgb[2][0] * X + xyzrgb[2][1] * Y + xyzrgb[2][2] * Z;
  rgb->r = dblToCol(pow(clip01(r * kr), 0.5));
  rgb->g = dblToCol(pow(clip01(g * kg), 0.5));
  rgb->b = dblToCol(pow(clip01(b * kb), 0.5));
  rgb->r = rgb->g = rgb->b = clip01(color->c[0]);
}

Project: poppler
File: GfxState.cc

void GfxDeviceRGBColorSpace::getRGB(GfxColor *color, GfxRGB *rgb) {
  rgb->r = clip01(color->c[0]);
  rgb->g = clip01(color->c[1]);
  rgb->b = clip01(color->c[2]);
}

Project: poppler

void GfxCalRGBColorSpace::getRGB(GfxColor *color, GfxRGB *rgb) {
  double X, Y, Z;
  double r, g, b;

  getXYZ(color,&X,&Y,&Z);
#ifdef USE_CMS
  if (XYZ2DisplayTransform != NULL && displayPixelType == PT_RGB) {
    Guchar out[gfxColorMaxComps];
    double in[gfxColorMaxComps];
    
    in[0] = clip01(X/whiteX);
    in[1] = clip01(Y/whiteY);
    in[2] = clip01(Z/whiteZ);
    XYZ2DisplayTransform->doTransform(in,out,1);
    rgb->r = byteToCol(out[0]);
    rgb->g = byteToCol(out[1]);
    rgb->b = byteToCol(out[2]);
    return;
  }
#endif
  r = xyzrgb[0][0] * X + xyzrgb[0][1] * Y + xyzrgb[0][2] * Z;
  g = xyzrgb[1][0] * X + xyzrgb[1][1] * Y + xyzrgb[1][2] * Z;
  b = xyzrgb[2][0] * X + xyzrgb[2][1] * Y + xyzrgb[2][2] * Z;
  rgb->r = dblToCol(pow(clip01(r), 0.5));
  rgb->g = dblToCol(pow(clip01(g), 0.5));
  rgb->b = dblToCol(pow(clip01(b), 0.5));
}

Project: poppler

void GfxDeviceCMYKColorSpace::getRGB(GfxColor *color, GfxRGB *rgb) {
  double c, m, y, k, c1, m1, y1, k1, r, g, b, x;
    
  c = colToDbl(color->c[0]);
  m = colToDbl(color->c[1]);
  y = colToDbl(color->c[2]);
  k = colToDbl(color->c[3]);
  c1 = 1 - c;
  m1 = 1 - m;
  y1 = 1 - y;
  k1 = 1 - k;
  x = c1 * m1 * y1 * k1; // 0 0 0 0
  r = g = b = x;
  x = c1 * m1 * y1 * k;  // 0 0 0 1
  r += 0.1373 * x;
  g += 0.1216 * x;
  b += 0.1255 * x;
  x = c1 * m1 * y  * k1; // 0 0 1 0
  r += x;
  g += 0.9490 * x;
  x = c1 * m1 * y  * k;  // 0 0 1 1
  r += 0.1098 * x;
  g += 0.1020 * x;
  x = c1 * m  * y1 * k1; // 0 1 0 0
  r += 0.9255 * x;
  b += 0.5490 * x;
  x = c1 * m  * y1 * k;  // 0 1 0 1
  r += 0.1412 * x;
  x = c1 * m  * y  * k1; // 0 1 1 0
  r += 0.9294 * x;
  g += 0.1098 * x;
  b += 0.1412 * x;
  x = c1 * m  * y  * k;  // 0 1 1 1
  r += 0.1333 * x;
  x = c  * m1 * y1 * k1; // 1 0 0 0
  g += 0.6784 * x;
  b += 0.9373 * x;
  x = c  * m1 * y1 * k;  // 1 0 0 1
  g += 0.0588 * x;
  b += 0.1412 * x;
  x = c  * m1 * y  * k1; // 1 0 1 0
  g += 0.6510 * x;
  b += 0.3137 * x;
  x = c  * m1 * y  * k;  // 1 0 1 1
  g += 0.0745 * x;
  x = c  * m  * y1 * k1; // 1 1 0 0
  r += 0.1804 * x;
  g += 0.1922 * x;
  b += 0.5725 * x;
  x = c  * m  * y1 * k;  // 1 1 0 1
  b += 0.0078 * x;
  x = c  * m  * y  * k1; // 1 1 1 0
  r += 0.2118 * x;
  g += 0.2119 * x;
  b += 0.2235 * x;
  rgb->r = clip01(dblToCol(r));
  rgb->g = clip01(dblToCol(g));
  rgb->b = clip01(dblToCol(b));
}

Project: poppler

void GfxLabColorSpace::getRGB(GfxColor *color, GfxRGB *rgb) {
  double X, Y, Z;
  double r, g, b;

  getXYZ(color, &X, &Y, &Z);
#ifdef USE_CMS
  if (XYZ2DisplayTransform != NULL && displayPixelType == PT_RGB) {
    Guchar out[gfxColorMaxComps];
    double in[gfxColorMaxComps];
    
    in[0] = clip01(X);
    in[1] = clip01(Y);
    in[2] = clip01(Z);
    XYZ2DisplayTransform->doTransform(in,out,1);
    rgb->r = byteToCol(out[0]);
    rgb->g = byteToCol(out[1]);
    rgb->b = byteToCol(out[2]);
    return;
  }
#endif
  X *= whiteX;
  Y *= whiteY;
  Z *= whiteZ;
  r = xyzrgb[0][0] * X + xyzrgb[0][1] * Y + xyzrgb[0][2] * Z;
  g = xyzrgb[1][0] * X + xyzrgb[1][1] * Y + xyzrgb[1][2] * Z;
  b = xyzrgb[2][0] * X + xyzrgb[2][1] * Y + xyzrgb[2][2] * Z;
  rgb->r = dblToCol(pow(clip01(r * kr), 0.5));
  rgb->g = dblToCol(pow(clip01(g * kg), 0.5));
  rgb->b = dblToCol(pow(clip01(b * kb), 0.5));
}

Project: poppler
File: GfxState.cc

void GfxICCBasedColorSpace::getRGB(GfxColor *color, GfxRGB *rgb) {
#ifdef USE_CMS
  if (transform != 0
       && (displayProfile == NULL || displayPixelType == PT_RGB)) {
    Guchar in[gfxColorMaxComps];
    Guchar out[gfxColorMaxComps];
    
    for (int i = 0;i < nComps;i++) {
	in[i] = colToByte(color->c[i]);
    }
    transform->doTransform(in,out,1);
    rgb->r = byteToCol(out[0]);
    rgb->g = byteToCol(out[1]);
    rgb->b = byteToCol(out[2]);
  } else {
    alt->getRGB(color, rgb);
  }
#else
  alt->getRGB(color, rgb);
#endif
}

Project: poppler
File: GfxState.cc

void GfxIndexedColorSpace::getRGB(GfxColor *color, GfxRGB *rgb) {
  GfxColor color2;

  base->getRGB(mapColorToBase(color, &color2), rgb);
}

Project: poppler
File: GfxState.cc

void GfxSeparationColorSpace::getRGB(GfxColor *color, GfxRGB *rgb) {
  double x;
  double c[gfxColorMaxComps];
  GfxColor color2;
  int i;

  x = colToDbl(color->c[0]);
  func->transform(&x, c);
  for (i = 0; i < alt->getNComps(); ++i) {
    color2.c[i] = dblToCol(c[i]);
  }
  alt->getRGB(&color2, rgb);
}

Project: poppler
File: GfxState.cc

void GfxDeviceNColorSpace::getRGB(GfxColor *color, GfxRGB *rgb) {
  double x[gfxColorMaxComps], c[gfxColorMaxComps];
  GfxColor color2;
  int i;

  for (i = 0; i < nComps; ++i) {
    x[i] = colToDbl(color->c[i]);
  }
  func->transform(x, c);
  for (i = 0; i < alt->getNComps(); ++i) {
    color2.c[i] = dblToCol(c[i]);
  }
  alt->getRGB(&color2, rgb);
}

Project: poppler
File: GfxState.cc

void GfxPatternColorSpace::getRGB(GfxColor *color, GfxRGB *rgb) {
  rgb->r = rgb->g = rgb->b = 0;
}

Project: poppler
File: GfxState.cc

void GfxImageColorMap::getRGB(Guchar *x, GfxRGB *rgb) {
  GfxColor color;
  int i;

  if (colorSpace2) {
    for (i = 0; i < nComps2; ++i) {
      color.c[i] = lookup[i][x[0]];
    }
    colorSpace2->getRGB(&color, rgb);
  } else {
    for (i = 0; i < nComps; ++i) {
      color.c[i] = lookup[i][x[i]];
    }
    colorSpace->getRGB(&color, rgb);
  }
}

Project: poppler
File: GfxState.cc

void GfxColorSpace::getRGBLine(Guchar *in, unsigned int *out, int length) {
  int i, j, n;
  GfxColor color;
  GfxRGB rgb;

  n = getNComps();
  for (i = 0; i < length; i++) {
    
    for (j = 0; j < n; j++)
      color.c[j] = in[i * n + j] * 256;

    getRGB (&color, &rgb);
    out[i] =
	((int) colToByte(rgb.r) << 16) |
	((int) colToByte(rgb.g) << 8) |
	((int) colToByte(rgb.b) << 0);
  }
}

Project: poppler
File: GfxState.cc

void GfxDeviceGrayColorSpace::getRGBLine(Guchar *in, unsigned int *out,
					 int length) {
  int i;

  for (i = 0; i < length; i++)
    out[i] = (in[i] << 16) | (in[i] << 8) | (in[i] << 0);
}

Project: poppler
File: GfxState.cc

void GfxDeviceRGBColorSpace::getRGBLine(Guchar *in, unsigned int *out,
					int length) {
  Guchar *p;
  int i;

  for (i = 0, p = in; i < length; i++, p += 3)
    out[i] = (p[0] << 16) | (p[1] << 8) | (p[2] << 0);
}

Project: poppler
File: GfxState.cc

void GfxICCBasedColorSpace::getRGBLine(Guchar *in, unsigned int *out,
				       int length) {
#ifdef USE_CMS
  if (lineTransform != 0) {
    for (int i = 0;i < length;i++) {
	Guchar tmp[gfxColorMaxComps];

	lineTransform->doTransform(in,tmp,1);
	in += nComps;
	out[i] = (tmp[0] << 16) | (tmp[1] << 8) | tmp[2];
    }
  } else {
    alt->getRGBLine(in, out, length);
  }
#else
  alt->getRGBLine(in, out, length);
#endif
}

Project: poppler
File: GfxState.cc

double GfxState::getTransformedFontSize() {
  double x1, y1, x2, y2;

  x1 = textMat[2] * fontSize;
  y1 = textMat[3] * fontSize;
  x2 = ctm[0] * x1 + ctm[2] * y1;
  y2 = ctm[1] * x1 + ctm[3] * y1;
  return sqrt(x2 * x2 + y2 * y2);
}

Project: poppler
File: GfxState.cc

void GfxGouraudTriangleShading::getTriangle(
				    int i,
				    double *x0, double *y0, GfxColor *color0,
				    double *x1, double *y1, GfxColor *color1,
				    double *x2, double *y2, GfxColor *color2) {
  double in;
  double out[gfxColorMaxComps];
  int v, j;

  v = triangles[i][0];
  *x0 = vertices[v].x;
  *y0 = vertices[v].y;
  if (nFuncs > 0) {
    in = colToDbl(vertices[v].color.c[0]);
    for (j = 0; j < nFuncs; ++j) {
      funcs[j]->transform(&in, &out[j]);
    }
    for (j = 0; j < gfxColorMaxComps; ++j) {
      color0->c[j] = dblToCol(out[j]);
    }
  } else {
    *color0 = vertices[v].color;
  }
  v = triangles[i][1];
  *x1 = vertices[v].x;
  *y1 = vertices[v].y;
  if (nFuncs > 0) {
    in = colToDbl(vertices[v].color.c[0]);
    for (j = 0; j < nFuncs; ++j) {
      funcs[j]->transform(&in, &out[j]);
    }
    for (j = 0; j < gfxColorMaxComps; ++j) {
      color1->c[j] = dblToCol(out[j]);
    }
  } else {
    *color1 = vertices[v].color;
  }
  v = triangles[i][2];
  *x2 = vertices[v].x;
  *y2 = vertices[v].y;
  if (nFuncs > 0) {
    in = colToDbl(vertices[v].color.c[0]);
    for (j = 0; j < nFuncs; ++j) {
      funcs[j]->transform(&in, &out[j]);
    }
    for (j = 0; j < gfxColorMaxComps; ++j) {
      color2->c[j] = dblToCol(out[j]);
    }
  } else {
    *color2 = vertices[v].color;
  }
}

Project: poppler

void GfxState::getUserClipBBox(double *xMin, double *yMin,
			       double *xMax, double *yMax) {
  double ictm[6];
  double xMin1, yMin1, xMax1, yMax1, det, tx, ty;

  det = 1 / (ctm[0] * ctm[3] - ctm[1] * ctm[2]);
  ictm[0] = ctm[3] * det;
  ictm[1] = -ctm[1] * det;
  ictm[2] = -ctm[2] * det;
  ictm[3] = ctm[0] * det;
  ictm[4] = (ctm[2] * ctm[5] - ctm[3] * ctm[4]) * det;
  ictm[5] = (ctm[1] * ctm[4] - ctm[0] * ctm[5]) * det;

  xMin1 = xMax1 = clipXMin * ictm[0] + clipYMin * ictm[2] + ictm[4];
  yMin1 = yMax1 = clipXMin * ictm[1] + clipYMin * ictm[3] + ictm[5];
  tx = clipXMin * ictm[0] + clipYMax * ictm[2] + ictm[4];
  ty = clipXMin * ictm[1] + clipYMax * ictm[3] + ictm[5];
  if (tx < xMin1) {
    xMin1 = tx;
  } else if (tx > xMax1) {
    xMax1 = tx;
  }
  if (ty < yMin1) {
    yMin1 = ty;
  } else if (ty > yMax1) {
    yMax1 = ty;
  }
  tx = clipXMax * ictm[0] + clipYMin * ictm[2] + ictm[4];
  ty = clipXMax * ictm[1] + clipYMin * ictm[3] + ictm[5];
  if (tx < xMin1) {
    xMin1 = tx;
  } else if (tx > xMax1) {
    xMax1 = tx;
  }
  if (ty < yMin1) {
    yMin1 = ty;
  } else if (ty > yMax1) {
    yMax1 = ty;
  }
  tx = clipXMax * ictm[0] + clipYMax * ictm[2] + ictm[4];
  ty = clipXMax * ictm[1] + clipYMax * ictm[3] + ictm[5];
  if (tx < xMin1) {
    xMin1 = tx;
  } else if (tx > xMax1) {
    xMax1 = tx;
  }
  if (ty < yMin1) {
    yMin1 = ty;
  } else if (ty > yMax1) {
    yMax1 = ty;
  }

  *xMin = xMin1;
  *yMin = yMin1;
  *xMax = xMax1;
  *yMax = yMax1;
}

Project: poppler
File: GfxState.cc

void GfxCalRGBColorSpace::getXYZ(GfxColor *color, 
  double *pX, double *pY, double *pZ) {
  double A, B, C;

  A = colToDbl(color->c[0]);
  B = colToDbl(color->c[1]);
  C = colToDbl(color->c[2]);
  *pX = mat[0]*pow(A,gammaR)+mat[3]*pow(B,gammaG)+mat[6]*pow(C,gammaB);
  *pY = mat[1]*pow(A,gammaR)+mat[4]*pow(B,gammaG)+mat[7]*pow(C,gammaB);
  *pZ = mat[2]*pow(A,gammaR)+mat[5]*pow(B,gammaG)+mat[8]*pow(C,gammaB);
}

Project: poppler
File: GfxState.cc

void GfxLabColorSpace::getXYZ(GfxColor *color, 
  double *pX, double *pY, double *pZ) {
  double X, Y, Z;
  double t1, t2;

  t1 = (colToDbl(color->c[0]) + 16) / 116;
  t2 = t1 + colToDbl(color->c[1]) / 500;
  if (t2 >= (6.0 / 29.0)) {
    X = t2 * t2 * t2;
  } else {
    X = (108.0 / 841.0) * (t2 - (4.0 / 29.0));
  }
  if (t1 >= (6.0 / 29.0)) {
    Y = t1 * t1 * t1;
  } else {
    Y = (108.0 / 841.0) * (t1 - (4.0 / 29.0));
  }
  t2 = t1 - colToDbl(color->c[2]) / 200;
  if (t2 >= (6.0 / 29.0)) {
    Z = t2 * t2 * t2;
  } else {
    Z = (108.0 / 841.0) * (t2 - (4.0 / 29.0));
  }
  *pX = X;
  *pY = Y;
  *pZ = Z;
}

Project: poppler
File: GfxState.cc

GBool GfxShading::init(Dict *dict) {
  Object obj1, obj2;
  int i;

  dict->lookup("ColorSpace", &obj1);
  if (!(colorSpace = GfxColorSpace::parse(&obj1))) {
    error(-1, "Bad color space in shading dictionary");
    obj1.free();
    return gFalse;
  }
  obj1.free();

  for (i = 0; i < gfxColorMaxComps; ++i) {
    background.c[i] = 0;
  }
  hasBackground = gFalse;
  if (dict->lookup("Background", &obj1)->isArray()) {
    if (obj1.arrayGetLength() == colorSpace->getNComps()) {
      hasBackground = gTrue;
      for (i = 0; i < colorSpace->getNComps(); ++i) {
	background.c[i] = dblToCol(obj1.arrayGet(i, &obj2)->getNum());
	obj2.free();
      }
    } else {
      error(-1, "Bad Background in shading dictionary");
    }
  }
  obj1.free();

  xMin = yMin = xMax = yMax = 0;
  hasBBox = gFalse;
  if (dict->lookup("BBox", &obj1)->isArray()) {
    if (obj1.arrayGetLength() == 4) {
      hasBBox = gTrue;
      xMin = obj1.arrayGet(0, &obj2)->getNum();
      obj2.free();
      yMin = obj1.arrayGet(1, &obj2)->getNum();
      obj2.free();
      xMax = obj1.arrayGet(2, &obj2)->getNum();
      obj2.free();
      yMax = obj1.arrayGet(3, &obj2)->getNum();
      obj2.free();
    } else {
      error(-1, "Bad BBox in shading dictionary");
    }
  }
  obj1.free();

  return gTrue;
}

Project: poppler
File: GfxState.cc

GBool Matrix::invertTo(Matrix *other)
{
  double det;

  det = 1 / (m[0] * m[3] - m[1] * m[2]);
  other->m[0] = m[3] * det;
  other->m[1] = -m[1] * det;
  other->m[2] = -m[2] * det;
  other->m[3] = m[0] * det;
  other->m[4] = (m[2] * m[5] - m[3] * m[4]) * det;
  other->m[5] = (m[1] * m[4] - m[0] * m[5]) * det;

  return gTrue;
}

Project: poppler
File: GfxState.cc

void GfxSubpath::lineTo(double x1, double y1) {
  if (n >= size) {
    size += 16;
    x = (double *)greallocn(x, size, sizeof(double));
    y = (double *)greallocn(y, size, sizeof(double));
    curve = (GBool *)greallocn(curve, size, sizeof(GBool));
  }
  x[n] = x1;
  y[n] = y1;
  curve[n] = gFalse;
  ++n;
}

Project: poppler
File: GfxState.cc

GfxICCBasedColorSpace *GfxICCBasedCache::lookup(int numA, int genA)
{
  int i;

  if (cache[0].num == numA && cache[0].gen == genA) {
    return (GfxICCBasedColorSpace *)cache[0].colorSpace->copy();
  }
  for (i = 1;i < GFX_ICCBASED_CACHE_SIZE && cache[i].num > 0;i++) {
    if (cache[i].num == numA && cache[i].gen == genA) {
      int j;
      GfxICCBasedCache hit = cache[i];

      for (j = i;j > 0;j--) {
	if (cache[j - 1].num > 0) cache[j] = cache[j-1];
      }
      cache[0] = hit;
      return (GfxICCBasedColorSpace *)hit.colorSpace->copy();
    }
  }
  return NULL;
}

Project: poppler
File: GfxState.cc

GfxColor *GfxIndexedColorSpace::mapColorToBase(GfxColor *color,
					       GfxColor *baseColor) {
  Guchar *p;
  double low[gfxColorMaxComps], range[gfxColorMaxComps];
  int n, i;

  n = base->getNComps();
  base->getDefaultRanges(low, range, indexHigh);
  p = &lookup[(int)(colToDbl(color->c[0]) + 0.5) * n];
  for (i = 0; i < n; ++i) {
    baseColor->c[i] = dblToCol(low[i] + (p[i] / 255.0) * range[i]);
  }
  return baseColor;
}

Project: poppler
File: GfxState.cc

void GfxPath::moveTo(double x, double y) {
  justMoved = gTrue;
  firstX = x;
  firstY = y;
}

Project: poppler
File: GfxState.cc

void GfxSubpath::offset(double dx, double dy) {
  int i;

  for (i = 0; i < n; ++i) {
    x[i] += dx;
    y[i] += dy;
  }
}

Project: poppler
File: GfxState.cc

void GfxPath::offset(double dx, double dy) {
  int i;

  for (i = 0; i < n; ++i) {
    subpaths[i]->offset(dx, dy);
  }
}

Project: poppler
File: GfxState.cc

GfxColorSpace *GfxColorSpace::parse(Object *csObj) {
  GfxColorSpace *cs;
  Object obj1;

  cs = NULL;
  if (csObj->isName()) {
    if (csObj->isName("DeviceGray") || csObj->isName("G")) {
      cs = new GfxDeviceGrayColorSpace();
    } else if (csObj->isName("DeviceRGB") || csObj->isName("RGB")) {
      cs = new GfxDeviceRGBColorSpace();
    } else if (csObj->isName("DeviceCMYK") || csObj->isName("CMYK")) {
      cs = new GfxDeviceCMYKColorSpace();
    } else if (csObj->isName("Pattern")) {
      cs = new GfxPatternColorSpace(NULL);
    } else {
      error(-1, "Bad color space '%s'", csObj->getName());
    }
  } else if (csObj->isArray()) {
    csObj->arrayGet(0, &obj1);
    if (obj1.isName("DeviceGray") || obj1.isName("G")) {
      cs = new GfxDeviceGrayColorSpace();
    } else if (obj1.isName("DeviceRGB") || obj1.isName("RGB")) {
      cs = new GfxDeviceRGBColorSpace();
    } else if (obj1.isName("DeviceCMYK") || obj1.isName("CMYK")) {
      cs = new GfxDeviceCMYKColorSpace();
    } else if (obj1.isName("CalGray")) {
      cs = GfxCalGrayColorSpace::parse(csObj->getArray());
    } else if (obj1.isName("CalRGB")) {
      cs = GfxCalRGBColorSpace::parse(csObj->getArray());
    } else if (obj1.isName("Lab")) {
      cs = GfxLabColorSpace::parse(csObj->getArray());
    } else if (obj1.isName("ICCBased")) {
      cs = GfxICCBasedColorSpace::parse(csObj->getArray());
    } else if (obj1.isName("Indexed") || obj1.isName("I")) {
      cs = GfxIndexedColorSpace::parse(csObj->getArray());
    } else if (obj1.isName("Separation")) {
      cs = GfxSeparationColorSpace::parse(csObj->getArray());
    } else if (obj1.isName("DeviceN")) {
      cs = GfxDeviceNColorSpace::parse(csObj->getArray());
    } else if (obj1.isName("Pattern")) {
      cs = GfxPatternColorSpace::parse(csObj->getArray());
    } else {
      error(-1, "Bad color space");
    }
    obj1.free();
  } else {
    error(-1, "Bad color space - expected name or array");
  }
  return cs;
}

Project: poppler
File: GfxState.cc

GfxColorSpace *GfxCalGrayColorSpace::parse(Array *arr) {
  GfxCalGrayColorSpace *cs;
  Object obj1, obj2, obj3;

  arr->get(1, &obj1);
  if (!obj1.isDict()) {
    error(-1, "Bad CalGray color space");
    obj1.free();
    return NULL;
  }
  cs = new GfxCalGrayColorSpace();
  if (obj1.dictLookup("WhitePoint", &obj2)->isArray() &&
      obj2.arrayGetLength() == 3) {
    obj2.arrayGet(0, &obj3);
    cs->whiteX = obj3.getNum();
    obj3.free();
    obj2.arrayGet(1, &obj3);
    cs->whiteY = obj3.getNum();
    obj3.free();
    obj2.arrayGet(2, &obj3);
    cs->whiteZ = obj3.getNum();
    obj3.free();
  }
  obj2.free();
  if (obj1.dictLookup("BlackPoint", &obj2)->isArray() &&
      obj2.arrayGetLength() == 3) {
    obj2.arrayGet(0, &obj3);
    cs->blackX = obj3.getNum();
    obj3.free();
    obj2.arrayGet(1, &obj3);
    cs->blackY = obj3.getNum();
    obj3.free();
    obj2.arrayGet(2, &obj3);
    cs->blackZ = obj3.getNum();
    obj3.free();
  }
  obj2.free();
  if (obj1.dictLookup("Gamma", &obj2)->isNum()) {
    cs->gamma = obj2.getNum();
  }
  obj2.free();
  obj1.free();

  cs->kr = 1 / (xyzrgb[0][0] * cs->whiteX +
		xyzrgb[0][1] * cs->whiteY +
		xyzrgb[0][2] * cs->whiteZ);
  cs->kg = 1 / (xyzrgb[1][0] * cs->whiteX +
		xyzrgb[1][1] * cs->whiteY +
		xyzrgb[1][2] * cs->whiteZ);
  cs->kb = 1 / (xyzrgb[2][0] * cs->whiteX +
		xyzrgb[2][1] * cs->whiteY +
		xyzrgb[2][2] * cs->whiteZ);

  return cs;
}

Project: poppler
File: GfxState.cc

GfxColorSpace *GfxCalRGBColorSpace::parse(Array *arr) {
  GfxCalRGBColorSpace *cs;
  Object obj1, obj2, obj3;
  int i;

  arr->get(1, &obj1);
  if (!obj1.isDict()) {
    error(-1, "Bad CalRGB color space");
    obj1.free();
    return NULL;
  }
  cs = new GfxCalRGBColorSpace();
  if (obj1.dictLookup("WhitePoint", &obj2)->isArray() &&
      obj2.arrayGetLength() == 3) {
    obj2.arrayGet(0, &obj3);
    cs->whiteX = obj3.getNum();
    obj3.free();
    obj2.arrayGet(1, &obj3);
    cs->whiteY = obj3.getNum();
    obj3.free();
    obj2.arrayGet(2, &obj3);
    cs->whiteZ = obj3.getNum();
    obj3.free();
  }
  obj2.free();
  if (obj1.dictLookup("BlackPoint", &obj2)->isArray() &&
      obj2.arrayGetLength() == 3) {
    obj2.arrayGet(0, &obj3);
    cs->blackX = obj3.getNum();
    obj3.free();
    obj2.arrayGet(1, &obj3);
    cs->blackY = obj3.getNum();
    obj3.free();
    obj2.arrayGet(2, &obj3);
    cs->blackZ = obj3.getNum();
    obj3.free();
  }
  obj2.free();
  if (obj1.dictLookup("Gamma", &obj2)->isArray() &&
      obj2.arrayGetLength() == 3) {
    obj2.arrayGet(0, &obj3);
    cs->gammaR = obj3.getNum();
    obj3.free();
    obj2.arrayGet(1, &obj3);
    cs->gammaG = obj3.getNum();
    obj3.free();
    obj2.arrayGet(2, &obj3);
    cs->gammaB = obj3.getNum();
    obj3.free();
  }
  obj2.free();
  if (obj1.dictLookup("Matrix", &obj2)->isArray() &&
      obj2.arrayGetLength() == 9) {
    for (i = 0; i < 9; ++i) {
      obj2.arrayGet(i, &obj3);
      cs->mat[i] = obj3.getNum();
      obj3.free();
    }
  }
  obj2.free();
  obj1.free();

  cs->kr = 1 / (xyzrgb[0][0] * cs->whiteX +
		xyzrgb[0][1] * cs->whiteY +
		xyzrgb[0][2] * cs->whiteZ);
  cs->kg = 1 / (xyzrgb[1][0] * cs->whiteX +
		xyzrgb[1][1] * cs->whiteY +
		xyzrgb[1][2] * cs->whiteZ);
  cs->kb = 1 / (xyzrgb[2][0] * cs->whiteX +
		xyzrgb[2][1] * cs->whiteY +
		xyzrgb[2][2] * cs->whiteZ);

  return cs;
}

Project: poppler

GfxColorSpace *GfxICCBasedColorSpace::parse(Array *arr) {
  GfxICCBasedColorSpace *cs;
  Ref iccProfileStreamA;
  int nCompsA;
  GfxColorSpace *altA;
  Dict *dict;
  Object obj1, obj2, obj3;
  int i;

  arr->getNF(1, &obj1);
  if (obj1.isRef()) {
    iccProfileStreamA = obj1.getRef();
  } else {
    iccProfileStreamA.num = 0;
    iccProfileStreamA.gen = 0;
  }
  obj1.free();
#ifdef USE_CMS
  if (iccProfileStreamA.num > 0
     && (cs = GfxICCBasedCache::lookup(iccProfileStreamA.num,
          iccProfileStreamA.gen)) != NULL) return cs;
#endif
  arr->get(1, &obj1);
  if (!obj1.isStream()) {
    error(-1, "Bad ICCBased color space (stream)");
    obj1.free();
    return NULL;
  }
  dict = obj1.streamGetDict();
  if (!dict->lookup("N", &obj2)->isInt()) {
    error(-1, "Bad ICCBased color space (N)");
    obj2.free();
    obj1.free();
    return NULL;
  }
  nCompsA = obj2.getInt();
  obj2.free();
  if (nCompsA > gfxColorMaxComps) {
    error(-1, "ICCBased color space with too many (%d > %d) components",
	  nCompsA, gfxColorMaxComps);
    nCompsA = gfxColorMaxComps;
  }
  if (dict->lookup("Alternate", &obj2)->isNull() ||
      !(altA = GfxColorSpace::parse(&obj2))) {
    switch (nCompsA) {
    case 1:
      altA = new GfxDeviceGrayColorSpace();
      break;
    case 3:
      altA = new GfxDeviceRGBColorSpace();
      break;
    case 4:
      altA = new GfxDeviceCMYKColorSpace();
      break;
    default:
      error(-1, "Bad ICCBased color space - invalid N");
      obj2.free();
      obj1.free();
      return NULL;
    }
  }
  obj2.free();
  cs = new GfxICCBasedColorSpace(nCompsA, altA, &iccProfileStreamA);
  if (dict->lookup("Range", &obj2)->isArray() &&
      obj2.arrayGetLength() == 2 * nCompsA) {
    for (i = 0; i < nCompsA; ++i) {
      obj2.arrayGet(2*i, &obj3);
      cs->rangeMin[i] = obj3.getNum();
      obj3.free();
      obj2.arrayGet(2*i+1, &obj3);
      cs->rangeMax[i] = obj3.getNum();
      obj3.free();
    }
  }
  obj2.free();
  obj1.free();

#ifdef USE_CMS
  arr->get(1, &obj1);
  dict = obj1.streamGetDict();
  Guchar *profBuf;
  unsigned int bufSize;
  Stream *iccStream = obj1.getStream();
  int c;
  unsigned int size = 0;

  bufSize = 65536;
  profBuf = (Guchar *)gmallocn(bufSize,1);
  iccStream->reset();
  while ((c = iccStream->getChar()) != EOF) {
    if (bufSize <= size) {
      bufSize += 65536;
      profBuf = (Guchar *)greallocn(profBuf,bufSize,1);
    }
    profBuf[size++] = c;
  }
  cmsHPROFILE hp = cmsOpenProfileFromMem(profBuf,size);
  gfree(profBuf);
  if (hp == 0) {
    error(-1, "read ICCBased color space profile error");
  } else {
    cmsHPROFILE dhp = displayProfile;
    if (dhp == NULL) dhp = RGBProfile;
    unsigned int cst = getCMSColorSpaceType(cmsGetColorSpace(hp));
    unsigned int dNChannels = getCMSNChannels(cmsGetColorSpace(dhp));
    unsigned int dcst = getCMSColorSpaceType(cmsGetColorSpace(dhp));
    cmsHTRANSFORM transform;
    if ((transform = cmsCreateTransform(hp,
	   COLORSPACE_SH(cst) |CHANNELS_SH(nCompsA) | BYTES_SH(1),
	   dhp,
	   COLORSPACE_SH(dcst) |
	     CHANNELS_SH(dNChannels) | BYTES_SH(1),
	  INTENT_RELATIVE_COLORIMETRIC,0)) == 0) {
      error(-1, "Can't create transform");
    }
    cs->transform = new GfxColorTransform(transform);
    if (dcst == PT_RGB) {
      if ((transform = cmsCreateTransform(hp,
	    CHANNELS_SH(nCompsA) | BYTES_SH(1),dhp,
	    TYPE_RGB_8,INTENT_RELATIVE_COLORIMETRIC,0)) == 0) {
	error(-1, "Can't create transform");
      }
      cs->lineTransform = new GfxColorTransform(transform);
    }
    cmsCloseProfile(hp);
  }
  obj1.free();
  if (iccProfileStreamA.num > 0) {
    GfxICCBasedCache::put(iccProfileStreamA.num,iccProfileStreamA.gen,cs);
  }
#endif
  return cs;
}

Project: poppler

GfxColorSpace *GfxIndexedColorSpace::parse(Array *arr) {
  GfxIndexedColorSpace *cs;
  GfxColorSpace *baseA;
  int indexHighA;
  Object obj1;
  int x;
  char *s;
  int n, i, j;

  if (arr->getLength() != 4) {
    error(-1, "Bad Indexed color space");
    goto err1;
  }
  arr->get(1, &obj1);
  if (!(baseA = GfxColorSpace::parse(&obj1))) {
    error(-1, "Bad Indexed color space (base color space)");
    goto err2;
  }
  obj1.free();
  if (!arr->get(2, &obj1)->isInt()) {
    error(-1, "Bad Indexed color space (hival)");
    delete baseA;
    goto err2;
  }
  indexHighA = obj1.getInt();
  if (indexHighA < 0 || indexHighA > 255) {
    int previousValue = indexHighA;
    if (indexHighA < 0) indexHighA = 0;
    else indexHighA = 255;
    error(-1, "Bad Indexed color space (invalid indexHigh value, was %d using %d to try to recover)", previousValue, indexHighA);
  }
  obj1.free();
  cs = new GfxIndexedColorSpace(baseA, indexHighA);
  arr->get(3, &obj1);
  n = baseA->getNComps();
  if (obj1.isStream()) {
    obj1.streamReset();
    for (i = 0; i <= indexHighA; ++i) {
      for (j = 0; j < n; ++j) {
	if ((x = obj1.streamGetChar()) == EOF) {
	  error(-1, "Bad Indexed color space (lookup table stream too short) padding with zeroes");
	  x = 0;
	}
	cs->lookup[i*n + j] = (Guchar)x;
      }
    }
    obj1.streamClose();
  } else if (obj1.isString()) {
    if (obj1.getString()->getLength() < (indexHighA + 1) * n) {
      error(-1, "Bad Indexed color space (lookup table string too short)");
      goto err3;
    }
    s = obj1.getString()->getCString();
    for (i = 0; i <= indexHighA; ++i) {
      for (j = 0; j < n; ++j) {
	cs->lookup[i*n + j] = (Guchar)*s++;
      }
    }
  } else {
    error(-1, "Bad Indexed color space (lookup table)");
    goto err3;
  }
  obj1.free();
  return cs;

 err3:
  delete cs;
 err2:
  obj1.free();
 err1:
  return NULL;
}

Project: poppler
File: GfxState.cc

GfxColorSpace *GfxSeparationColorSpace::parse(Array *arr) {
  GfxSeparationColorSpace *cs;
  GooString *nameA;
  GfxColorSpace *altA;
  Function *funcA;
  Object obj1;

  if (arr->getLength() != 4) {
    error(-1, "Bad Separation color space");
    goto err1;
  }
  if (!arr->get(1, &obj1)->isName()) {
    error(-1, "Bad Separation color space (name)");
    goto err2;
  }
  nameA = new GooString(obj1.getName());
  obj1.free();
  arr->get(2, &obj1);
  if (!(altA = GfxColorSpace::parse(&obj1))) {
    error(-1, "Bad Separation color space (alternate color space)");
    goto err3;
  }
  obj1.free();
  arr->get(3, &obj1);
  if (!(funcA = Function::parse(&obj1))) {
    goto err4;
  }
  obj1.free();
  cs = new GfxSeparationColorSpace(nameA, altA, funcA);
  return cs;

 err4:
  delete altA;
 err3:
  delete nameA;
 err2:
  obj1.free();
 err1:
  return NULL;
}

Project: poppler
File: GfxState.cc

GfxColorSpace *GfxDeviceNColorSpace::parse(Array *arr) {
  GfxDeviceNColorSpace *cs;
  int nCompsA;
  GooString *namesA[gfxColorMaxComps];
  GfxColorSpace *altA;
  Function *funcA;
  Object obj1, obj2;
  int i;

  if (arr->getLength() != 4 && arr->getLength() != 5) {
    error(-1, "Bad DeviceN color space");
    goto err1;
  }
  if (!arr->get(1, &obj1)->isArray()) {
    error(-1, "Bad DeviceN color space (names)");
    goto err2;
  }
  nCompsA = obj1.arrayGetLength();
  if (nCompsA > gfxColorMaxComps) {
    error(-1, "DeviceN color space with too many (%d > %d) components",
	  nCompsA, gfxColorMaxComps);
    nCompsA = gfxColorMaxComps;
  }
  for (i = 0; i < nCompsA; ++i) {
    if (!obj1.arrayGet(i, &obj2)->isName()) {
      error(-1, "Bad DeviceN color space (names)");
      obj2.free();
      goto err2;
    }
    namesA[i] = new GooString(obj2.getName());
    obj2.free();
  }
  obj1.free();
  arr->get(2, &obj1);
  if (!(altA = GfxColorSpace::parse(&obj1))) {
    error(-1, "Bad DeviceN color space (alternate color space)");
    goto err3;
  }
  obj1.free();
  arr->get(3, &obj1);
  if (!(funcA = Function::parse(&obj1))) {
    goto err4;
  }
  obj1.free();
  cs = new GfxDeviceNColorSpace(nCompsA, altA, funcA);
  cs->nonMarking = gTrue;
  for (i = 0; i < nCompsA; ++i) {
    cs->names[i] = namesA[i];
    if (namesA[i]->cmp("None")) {
      cs->nonMarking = gFalse;
    }
  }
  return cs;

 err4:
  delete altA;
 err3:
  for (i = 0; i < nCompsA; ++i) {
    delete namesA[i];
  }
 err2:
  obj1.free();
 err1:
  return NULL;
}

Project: poppler
File: GfxState.cc

GfxColorSpace *GfxPatternColorSpace::parse(Array *arr) {
  GfxPatternColorSpace *cs;
  GfxColorSpace *underA;
  Object obj1;

  if (arr->getLength() != 1 && arr->getLength() != 2) {
    error(-1, "Bad Pattern color space");
    return NULL;
  }
  underA = NULL;
  if (arr->getLength() == 2) {
    arr->get(1, &obj1);
    if (!(underA = GfxColorSpace::parse(&obj1))) {
      error(-1, "Bad Pattern color space (underlying color space)");
      obj1.free();
      return NULL;
    }
    obj1.free();
  }
  cs = new GfxPatternColorSpace(underA);
  return cs;
}

Project: poppler
File: GfxState.cc

GfxPattern *GfxPattern::parse(Object *obj) {
  GfxPattern *pattern;
  Object obj1;

  if (obj->isDict()) {
    obj->dictLookup("PatternType", &obj1);
  } else if (obj->isStream()) {
    obj->streamGetDict()->lookup("PatternType", &obj1);
  } else {
    return NULL;
  }
  pattern = NULL;
  if (obj1.isInt() && obj1.getInt() == 1) {
    pattern = GfxTilingPattern::parse(obj);
  } else if (obj1.isInt() && obj1.getInt() == 2) {
    pattern = GfxShadingPattern::parse(obj);
  }
  obj1.free();
  return pattern;
}

Project: poppler
File: GfxState.cc

GfxTilingPattern *GfxTilingPattern::parse(Object *patObj) {
  GfxTilingPattern *pat;
  Dict *dict;
  int paintTypeA, tilingTypeA;
  double bboxA[4], matrixA[6];
  double xStepA, yStepA;
  Object resDictA;
  Object obj1, obj2;
  int i;

  if (!patObj->isStream()) {
    return NULL;
  }
  dict = patObj->streamGetDict();

  if (dict->lookup("PaintType", &obj1)->isInt()) {
    paintTypeA = obj1.getInt();
  } else {
    paintTypeA = 1;
    error(-1, "Invalid or missing PaintType in pattern");
  }
  obj1.free();
  if (dict->lookup("TilingType", &obj1)->isInt()) {
    tilingTypeA = obj1.getInt();
  } else {
    tilingTypeA = 1;
    error(-1, "Invalid or missing TilingType in pattern");
  }
  obj1.free();
  bboxA[0] = bboxA[1] = 0;
  bboxA[2] = bboxA[3] = 1;
  if (dict->lookup("BBox", &obj1)->isArray() &&
      obj1.arrayGetLength() == 4) {
    for (i = 0; i < 4; ++i) {
      if (obj1.arrayGet(i, &obj2)->isNum()) {
	bboxA[i] = obj2.getNum();
      }
      obj2.free();
    }
  } else {
    error(-1, "Invalid or missing BBox in pattern");
  }
  obj1.free();
  if (dict->lookup("XStep", &obj1)->isNum()) {
    xStepA = obj1.getNum();
  } else {
    xStepA = 1;
    error(-1, "Invalid or missing XStep in pattern");
  }
  obj1.free();
  if (dict->lookup("YStep", &obj1)->isNum()) {
    yStepA = obj1.getNum();
  } else {
    yStepA = 1;
    error(-1, "Invalid or missing YStep in pattern");
  }
  obj1.free();
  if (!dict->lookup("Resources", &resDictA)->isDict()) {
    resDictA.free();
    resDictA.initNull();
    error(-1, "Invalid or missing Resources in pattern");
  }
  matrixA[0] = 1; matrixA[1] = 0;
  matrixA[2] = 0; matrixA[3] = 1;
  matrixA[4] = 0; matrixA[5] = 0;
  if (dict->lookup("Matrix", &obj1)->isArray() &&
      obj1.arrayGetLength() == 6) {
    for (i = 0; i < 6; ++i) {
      if (obj1.arrayGet(i, &obj2)->isNum()) {
	matrixA[i] = obj2.getNum();
      }
      obj2.free();
    }
  }
  obj1.free();

  pat = new GfxTilingPattern(paintTypeA, tilingTypeA, bboxA, xStepA, yStepA,
			     &resDictA, matrixA, patObj);
  resDictA.free();
  return pat;
}

Project: poppler
File: GfxState.cc

GfxShadingPattern *GfxShadingPattern::parse(Object *patObj) {
  Dict *dict;
  GfxShading *shadingA;
  double matrixA[6];
  Object obj1, obj2;
  int i;

  if (!patObj->isDict()) {
    return NULL;
  }
  dict = patObj->getDict();

  dict->lookup("Shading", &obj1);
  shadingA = GfxShading::parse(&obj1);
  obj1.free();
  if (!shadingA) {
    return NULL;
  }

  matrixA[0] = 1; matrixA[1] = 0;
  matrixA[2] = 0; matrixA[3] = 1;
  matrixA[4] = 0; matrixA[5] = 0;
  if (dict->lookup("Matrix", &obj1)->isArray() &&
      obj1.arrayGetLength() == 6) {
    for (i = 0; i < 6; ++i) {
      if (obj1.arrayGet(i, &obj2)->isNum()) {
	matrixA[i] = obj2.getNum();
      }
      obj2.free();
    }
  }
  obj1.free();

  return new GfxShadingPattern(shadingA, matrixA);
}

Project: poppler
File: GfxState.cc

GfxShading *GfxShading::parse(Object *obj) {
  GfxShading *shading;
  Dict *dict;
  int typeA;
  Object obj1;

  if (obj->isDict()) {
    dict = obj->getDict();
  } else if (obj->isStream()) {
    dict = obj->streamGetDict();
  } else {
    return NULL;
  }

  if (!dict->lookup("ShadingType", &obj1)->isInt()) {
    error(-1, "Invalid ShadingType in shading dictionary");
    obj1.free();
    return NULL;
  }
  typeA = obj1.getInt();
  obj1.free();

  switch (typeA) {
  case 1:
    shading = GfxFunctionShading::parse(dict);
    break;
  case 2:
    shading = GfxAxialShading::parse(dict);
    break;
  case 3:
    shading = GfxRadialShading::parse(dict);
    break;
  case 4:
    if (obj->isStream()) {
      shading = GfxGouraudTriangleShading::parse(4, dict, obj->getStream());
    } else {
      error(-1, "Invalid Type 4 shading object");
      goto err1;
    }
    break;
  case 5:
    if (obj->isStream()) {
      shading = GfxGouraudTriangleShading::parse(5, dict, obj->getStream());
    } else {
      error(-1, "Invalid Type 5 shading object");
      goto err1;
    }
    break;
  case 6:
    if (obj->isStream()) {
      shading = GfxPatchMeshShading::parse(6, dict, obj->getStream());
    } else {
      error(-1, "Invalid Type 6 shading object");
      goto err1;
    }
    break;
  case 7:
    if (obj->isStream()) {
      shading = GfxPatchMeshShading::parse(7, dict, obj->getStream());
    } else {
      error(-1, "Invalid Type 7 shading object");
      goto err1;
    }
    break;
  default:
    error(-1, "Unimplemented shading type %d", typeA);
    goto err1;
  }

  return shading;

 err1:
  return NULL;
}

Project: poppler
File: GfxState.cc

GfxFunctionShading *GfxFunctionShading::parse(Dict *dict) {
  GfxFunctionShading *shading;
  double x0A, y0A, x1A, y1A;
  double matrixA[6];
  Function *funcsA[gfxColorMaxComps];
  int nFuncsA;
  Object obj1, obj2;
  int i;

  x0A = y0A = 0;
  x1A = y1A = 1;
  if (dict->lookup("Domain", &obj1)->isArray() &&
      obj1.arrayGetLength() == 4) {
    x0A = obj1.arrayGet(0, &obj2)->getNum();
    obj2.free();
    x1A = obj1.arrayGet(1, &obj2)->getNum();
    obj2.free();
    y0A = obj1.arrayGet(2, &obj2)->getNum();
    obj2.free();
    y1A = obj1.arrayGet(3, &obj2)->getNum();
    obj2.free();
  }
  obj1.free();

  matrixA[0] = 1; matrixA[1] = 0;
  matrixA[2] = 0; matrixA[3] = 1;
  matrixA[4] = 0; matrixA[5] = 0;
  if (dict->lookup("Matrix", &obj1)->isArray() &&
      obj1.arrayGetLength() == 6) {
    matrixA[0] = obj1.arrayGet(0, &obj2)->getNum();
    obj2.free();
    matrixA[1] = obj1.arrayGet(1, &obj2)->getNum();
    obj2.free();
    matrixA[2] = obj1.arrayGet(2, &obj2)->getNum();
    obj2.free();
    matrixA[3] = obj1.arrayGet(3, &obj2)->getNum();
    obj2.free();
    matrixA[4] = obj1.arrayGet(4, &obj2)->getNum();
    obj2.free();
    matrixA[5] = obj1.arrayGet(5, &obj2)->getNum();
    obj2.free();
  }
  obj1.free();

  dict->lookup("Function", &obj1);
  if (obj1.isArray()) {
    nFuncsA = obj1.arrayGetLength();
    if (nFuncsA > gfxColorMaxComps) {
      error(-1, "Invalid Function array in shading dictionary");
      goto err1;
    }
    for (i = 0; i < nFuncsA; ++i) {
      obj1.arrayGet(i, &obj2);
      if (!(funcsA[i] = Function::parse(&obj2))) {
	goto err2;
      }
      obj2.free();
    }
  } else {
    nFuncsA = 1;
    if (!(funcsA[0] = Function::parse(&obj1))) {
      goto err1;
    }
  }
  obj1.free();

  shading = new GfxFunctionShading(x0A, y0A, x1A, y1A, matrixA,
				   funcsA, nFuncsA);
  if (!shading->init(dict)) {
    delete shading;
    return NULL;
  }
  return shading;

 err2:
  obj2.free();
 err1:
  obj1.free();
  return NULL;
}

Project: poppler
File: GfxState.cc

GfxAxialShading *GfxAxialShading::parse(Dict *dict) {
  GfxAxialShading *shading;
  double x0A, y0A, x1A, y1A;
  double t0A, t1A;
  Function *funcsA[gfxColorMaxComps];
  int nFuncsA;
  GBool extend0A, extend1A;
  Object obj1, obj2;
  int i;

  x0A = y0A = x1A = y1A = 0;
  if (dict->lookup("Coords", &obj1)->isArray() &&
      obj1.arrayGetLength() == 4) {
    x0A = obj1.arrayGet(0, &obj2)->getNum();
    obj2.free();
    y0A = obj1.arrayGet(1, &obj2)->getNum();
    obj2.free();
    x1A = obj1.arrayGet(2, &obj2)->getNum();
    obj2.free();
    y1A = obj1.arrayGet(3, &obj2)->getNum();
    obj2.free();
  } else {
    error(-1, "Missing or invalid Coords in shading dictionary");
    goto err1;
  }
  obj1.free();

  t0A = 0;
  t1A = 1;
  if (dict->lookup("Domain", &obj1)->isArray() &&
      obj1.arrayGetLength() == 2) {
    t0A = obj1.arrayGet(0, &obj2)->getNum();
    obj2.free();
    t1A = obj1.arrayGet(1, &obj2)->getNum();
    obj2.free();
  }
  obj1.free();

  dict->lookup("Function", &obj1);
  if (obj1.isArray()) {
    nFuncsA = obj1.arrayGetLength();
    if (nFuncsA > gfxColorMaxComps) {
      error(-1, "Invalid Function array in shading dictionary");
      goto err1;
    }
    for (i = 0; i < nFuncsA; ++i) {
      obj1.arrayGet(i, &obj2);
      if (!(funcsA[i] = Function::parse(&obj2))) {
	obj1.free();
	obj2.free();
	goto err1;
      }
      obj2.free();
    }
  } else {
    nFuncsA = 1;
    if (!(funcsA[0] = Function::parse(&obj1))) {
      obj1.free();
      goto err1;
    }
  }
  obj1.free();

  extend0A = extend1A = gFalse;
  if (dict->lookup("Extend", &obj1)->isArray() &&
      obj1.arrayGetLength() == 2) {
    extend0A = obj1.arrayGet(0, &obj2)->getBool();
    obj2.free();
    extend1A = obj1.arrayGet(1, &obj2)->getBool();
    obj2.free();
  }
  obj1.free();

  shading = new GfxAxialShading(x0A, y0A, x1A, y1A, t0A, t1A,
				funcsA, nFuncsA, extend0A, extend1A);
  if (!shading->init(dict)) {
    delete shading;
    return NULL;
  }
  return shading;

 err1:
  return NULL;
}

Project: poppler
File: GfxState.cc

GfxRadialShading *GfxRadialShading::parse(Dict *dict) {
  GfxRadialShading *shading;
  double x0A, y0A, r0A, x1A, y1A, r1A;
  double t0A, t1A;
  Function *funcsA[gfxColorMaxComps];
  int nFuncsA;
  GBool extend0A, extend1A;
  Object obj1, obj2;
  int i;

  x0A = y0A = r0A = x1A = y1A = r1A = 0;
  if (dict->lookup("Coords", &obj1)->isArray() &&
      obj1.arrayGetLength() == 6) {
    x0A = obj1.arrayGet(0, &obj2)->getNum();
    obj2.free();
    y0A = obj1.arrayGet(1, &obj2)->getNum();
    obj2.free();
    r0A = obj1.arrayGet(2, &obj2)->getNum();
    obj2.free();
    x1A = obj1.arrayGet(3, &obj2)->getNum();
    obj2.free();
    y1A = obj1.arrayGet(4, &obj2)->getNum();
    obj2.free();
    r1A = obj1.arrayGet(5, &obj2)->getNum();
    obj2.free();
  } else {
    error(-1, "Missing or invalid Coords in shading dictionary");
    goto err1;
  }
  obj1.free();

  t0A = 0;
  t1A = 1;
  if (dict->lookup("Domain", &obj1)->isArray() &&
      obj1.arrayGetLength() == 2) {
    t0A = obj1.arrayGet(0, &obj2)->getNum();
    obj2.free();
    t1A = obj1.arrayGet(1, &obj2)->getNum();
    obj2.free();
  }
  obj1.free();

  dict->lookup("Function", &obj1);
  if (obj1.isArray()) {
    nFuncsA = obj1.arrayGetLength();
    if (nFuncsA > gfxColorMaxComps) {
      error(-1, "Invalid Function array in shading dictionary");
      goto err1;
    }
    for (i = 0; i < nFuncsA; ++i) {
      obj1.arrayGet(i, &obj2);
      if (!(funcsA[i] = Function::parse(&obj2))) {
	obj1.free();
	obj2.free();
	goto err1;
      }
      obj2.free();
    }
  } else {
    nFuncsA = 1;
    if (!(funcsA[0] = Function::parse(&obj1))) {
      obj1.free();
      goto err1;
    }
  }
  obj1.free();

  extend0A = extend1A = gFalse;
  if (dict->lookup("Extend", &obj1)->isArray() &&
      obj1.arrayGetLength() == 2) {
    extend0A = obj1.arrayGet(0, &obj2)->getBool();
    obj2.free();
    extend1A = obj1.arrayGet(1, &obj2)->getBool();
    obj2.free();
  }
  obj1.free();

  shading = new GfxRadialShading(x0A, y0A, r0A, x1A, y1A, r1A, t0A, t1A,
				 funcsA, nFuncsA, extend0A, extend1A);
  if (!shading->init(dict)) {
    delete shading;
    return NULL;
  }
  return shading;

 err1:
  return NULL;
}

Project: poppler
File: GfxState.cc

GfxPatchMeshShading *GfxPatchMeshShading::parse(int typeA, Dict *dict,
						Stream *str) {
  GfxPatchMeshShading *shading;
  Function *funcsA[gfxColorMaxComps];
  int nFuncsA;
  int coordBits, compBits, flagBits;
  double xMin, xMax, yMin, yMax;
  double cMin[gfxColorMaxComps], cMax[gfxColorMaxComps];
  double xMul, yMul;
  double cMul[gfxColorMaxComps];
  GfxPatch *patchesA, *p;
  int nComps, nPatchesA, patchesSize, nPts, nColors;
  Guint flag;
  double x[16], y[16];
  Guint xi, yi;
  GfxColorComp c[4][gfxColorMaxComps];
  Guint ci[4];
  GfxShadingBitBuf *bitBuf;
  Object obj1, obj2;
  int i, j;

  if (dict->lookup("BitsPerCoordinate", &obj1)->isInt()) {
    coordBits = obj1.getInt();
  } else {
    error(-1, "Missing or invalid BitsPerCoordinate in shading dictionary");
    goto err2;
  }
  obj1.free();
  if (dict->lookup("BitsPerComponent", &obj1)->isInt()) {
    compBits = obj1.getInt();
  } else {
    error(-1, "Missing or invalid BitsPerComponent in shading dictionary");
    goto err2;
  }
  obj1.free();
  if (dict->lookup("BitsPerFlag", &obj1)->isInt()) {
    flagBits = obj1.getInt();
  } else {
    error(-1, "Missing or invalid BitsPerFlag in shading dictionary");
    goto err2;
  }
  obj1.free();
  if (dict->lookup("Decode", &obj1)->isArray() &&
      obj1.arrayGetLength() >= 6) {
    xMin = obj1.arrayGet(0, &obj2)->getNum();
    obj2.free();
    xMax = obj1.arrayGet(1, &obj2)->getNum();
    obj2.free();
    xMul = (xMax - xMin) / (pow(2.0, coordBits) - 1);
    yMin = obj1.arrayGet(2, &obj2)->getNum();
    obj2.free();
    yMax = obj1.arrayGet(3, &obj2)->getNum();
    obj2.free();
    yMul = (yMax - yMin) / (pow(2.0, coordBits) - 1);
    for (i = 0; 5 + 2*i < obj1.arrayGetLength() && i < gfxColorMaxComps; ++i) {
      cMin[i] = obj1.arrayGet(4 + 2*i, &obj2)->getNum();
      obj2.free();
      cMax[i] = obj1.arrayGet(5 + 2*i, &obj2)->getNum();
      obj2.free();
      cMul[i] = (cMax[i] - cMin[i]) / (double)((1 << compBits) - 1);
    }
    nComps = i;
  } else {
    error(-1, "Missing or invalid Decode array in shading dictionary");
    goto err2;
  }
  obj1.free();

  if (!dict->lookup("Function", &obj1)->isNull()) {
    if (obj1.isArray()) {
      nFuncsA = obj1.arrayGetLength();
      if (nFuncsA > gfxColorMaxComps) {
	error(-1, "Invalid Function array in shading dictionary");
	goto err1;
      }
      for (i = 0; i < nFuncsA; ++i) {
	obj1.arrayGet(i, &obj2);
	if (!(funcsA[i] = Function::parse(&obj2))) {
	  obj1.free();
	  obj2.free();
	  goto err1;
	}
	obj2.free();
      }
    } else {
      nFuncsA = 1;
      if (!(funcsA[0] = Function::parse(&obj1))) {
	obj1.free();
	goto err1;
      }
    }
  } else {
    nFuncsA = 0;
  }
  obj1.free();

  nPatchesA = 0;
  patchesA = NULL;
  patchesSize = 0;
  bitBuf = new GfxShadingBitBuf(str);
  while (1) {
    if (!bitBuf->getBits(flagBits, &flag)) {
      break;
    }
    if (typeA == 6) {
      switch (flag) {
      case 0: nPts = 12; nColors = 4; break;
      case 1:
      case 2:
      case 3:
      default: nPts =  8; nColors = 2; break;
      }
    } else {
      switch (flag) {
      case 0: nPts = 16; nColors = 4; break;
      case 1:
      case 2:
      case 3:
      default: nPts = 12; nColors = 2; break;
      }
    }
    for (i = 0; i < nPts; ++i) {
      if (!bitBuf->getBits(coordBits, &xi) ||
	  !bitBuf->getBits(coordBits, &yi)) {
	break;
      }
      x[i] = xMin + xMul * (double)xi;
      y[i] = yMin + yMul * (double)yi;
    }
    if (i < nPts) {
      break;
    }
    for (i = 0; i < nColors; ++i) {
      for (j = 0; j < nComps; ++j) {
	if (!bitBuf->getBits(compBits, &ci[j])) {
	  break;
	}
	c[i][j] = dblToCol(cMin[j] + cMul[j] * (double)ci[j]);
      }
      if (j < nComps) {
	break;
      }
    }
    if (i < nColors) {
      break;
    }
    if (nPatchesA == patchesSize) {
      patchesSize = (patchesSize == 0) ? 16 : 2 * patchesSize;
      patchesA = (GfxPatch *)greallocn(patchesA,
				       patchesSize, sizeof(GfxPatch));
    }
    p = &patchesA[nPatchesA];
    if (typeA == 6) {
      switch (flag) {
      case 0:
	p->x[0][0] = x[0];
	p->y[0][0] = y[0];
	p->x[0][1] = x[1];
	p->y[0][1] = y[1];
	p->x[0][2] = x[2];
	p->y[0][2] = y[2];
	p->x[0][3] = x[3];
	p->y[0][3] = y[3];
	p->x[1][3] = x[4];
	p->y[1][3] = y[4];
	p->x[2][3] = x[5];
	p->y[2][3] = y[5];
	p->x[3][3] = x[6];
	p->y[3][3] = y[6];
	p->x[3][2] = x[7];
	p->y[3][2] = y[7];
	p->x[3][1] = x[8];
	p->y[3][1] = y[8];
	p->x[3][0] = x[9];
	p->y[3][0] = y[9];
	p->x[2][0] = x[10];
	p->y[2][0] = y[10];
	p->x[1][0] = x[11];
	p->y[1][0] = y[11];
	for (j = 0; j < nComps; ++j) {
	  p->color[0][0].c[j] = c[0][j];
	  p->color[0][1].c[j] = c[1][j];
	  p->color[1][1].c[j] = c[2][j];
	  p->color[1][0].c[j] = c[3][j];
	}
	break;
      case 1:
	p->x[0][0] = patchesA[nPatchesA-1].x[0][3];
	p->y[0][0] = patchesA[nPatchesA-1].y[0][3];
	p->x[0][1] = patchesA[nPatchesA-1].x[1][3];
	p->y[0][1] = patchesA[nPatchesA-1].y[1][3];
	p->x[0][2] = patchesA[nPatchesA-1].x[2][3];
	p->y[0][2] = patchesA[nPatchesA-1].y[2][3];
	p->x[0][3] = patchesA[nPatchesA-1].x[3][3];
	p->y[0][3] = patchesA[nPatchesA-1].y[3][3];
	p->x[1][3] = x[0];
	p->y[1][3] = y[0];
	p->x[2][3] = x[1];
	p->y[2][3] = y[1];
	p->x[3][3] = x[2];
	p->y[3][3] = y[2];
	p->x[3][2] = x[3];
	p->y[3][2] = y[3];
	p->x[3][1] = x[4];
	p->y[3][1] = y[4];
	p->x[3][0] = x[5];
	p->y[3][0] = y[5];
	p->x[2][0] = x[6];
	p->y[2][0] = y[6];
	p->x[1][0] = x[7];
	p->y[1][0] = y[7];
	for (j = 0; j < nComps; ++j) {
	  p->color[0][0].c[j] = patchesA[nPatchesA-1].color[0][1].c[j];
	  p->color[0][1].c[j] = patchesA[nPatchesA-1].color[1][1].c[j];
	  p->color[1][1].c[j] = c[0][j];
	  p->color[1][0].c[j] = c[1][j];
	}
	break;
      case 2:
	p->x[0][0] = patchesA[nPatchesA-1].x[3][3];
	p->y[0][0] = patchesA[nPatchesA-1].y[3][3];
	p->x[0][1] = patchesA[nPatchesA-1].x[3][2];
	p->y[0][1] = patchesA[nPatchesA-1].y[3][2];
	p->x[0][2] = patchesA[nPatchesA-1].x[3][1];
	p->y[0][2] = patchesA[nPatchesA-1].y[3][1];
	p->x[0][3] = patchesA[nPatchesA-1].x[3][0];
	p->y[0][3] = patchesA[nPatchesA-1].y[3][0];
	p->x[1][3] = x[0];
	p->y[1][3] = y[0];
	p->x[2][3] = x[1];
	p->y[2][3] = y[1];
	p->x[3][3] = x[2];
	p->y[3][3] = y[2];
	p->x[3][2] = x[3];
	p->y[3][2] = y[3];
	p->x[3][1] = x[4];
	p->y[3][1] = y[4];
	p->x[3][0] = x[5];
	p->y[3][0] = y[5];
	p->x[2][0] = x[6];
	p->y[2][0] = y[6];
	p->x[1][0] = x[7];
	p->y[1][0] = y[7];
	for (j = 0; j < nComps; ++j) {
	  p->color[0][0].c[j] = patchesA[nPatchesA-1].color[1][1].c[j];
	  p->color[0][1].c[j] = patchesA[nPatchesA-1].color[1][0].c[j];
	  p->color[1][1].c[j] = c[0][j];
	  p->color[1][0].c[j] = c[1][j];
	}
	break;
      case 3:
	p->x[0][0] = patchesA[nPatchesA-1].x[3][0];
	p->y[0][0] = patchesA[nPatchesA-1].y[3][0];
	p->x[0][1] = patchesA[nPatchesA-1].x[2][0];
	p->y[0][1] = patchesA[nPatchesA-1].y[2][0];
	p->x[0][2] = patchesA[nPatchesA-1].x[1][0];
	p->y[0][2] = patchesA[nPatchesA-1].y[1][0];
	p->x[0][3] = patchesA[nPatchesA-1].x[0][0];
	p->y[0][3] = patchesA[nPatchesA-1].y[0][0];
	p->x[1][3] = x[0];
	p->y[1][3] = y[0];
	p->x[2][3] = x[1];
	p->y[2][3] = y[1];
	p->x[3][3] = x[2];
	p->y[3][3] = y[2];
	p->x[3][2] = x[3];
	p->y[3][2] = y[3];
	p->x[3][1] = x[4];
	p->y[3][1] = y[4];
	p->x[3][0] = x[5];
	p->y[3][0] = y[5];
	p->x[2][0] = x[6];
	p->y[2][0] = y[6];
	p->x[1][0] = x[7];
	p->y[1][0] = y[7];
	for (j = 0; j < nComps; ++j) {
	  p->color[0][1].c[j] = patchesA[nPatchesA-1].color[1][0].c[j];
	  p->color[0][1].c[j] = patchesA[nPatchesA-1].color[0][0].c[j];
	  p->color[1][1].c[j] = c[0][j];
	  p->color[1][0].c[j] = c[1][j];
	}
	break;
  }
    } else {
      switch (flag) {
      case 0:
	p->x[0][0] = x[0];
	p->y[0][0] = y[0];
	p->x[0][1] = x[1];
	p->y[0][1] = y[1];
	p->x[0][2] = x[2];
	p->y[0][2] = y[2];
	p->x[0][3] = x[3];
	p->y[0][3] = y[3];
	p->x[1][3] = x[4];
	p->y[1][3] = y[4];
	p->x[2][3] = x[5];
	p->y[2][3] = y[5];
	p->x[3][3] = x[6];
	p->y[3][3] = y[6];
	p->x[3][2] = x[7];
	p->y[3][2] = y[7];
	p->x[3][1] = x[8];
	p->y[3][1] = y[8];
	p->x[3][0] = x[9];
	p->y[3][0] = y[9];
	p->x[2][0] = x[10];
	p->y[2][0] = y[10];
	p->x[1][0] = x[11];
	p->y[1][0] = y[11];
	p->x[1][1] = x[12];
	p->y[1][1] = y[12];
	p->x[1][2] = x[13];
	p->y[1][2] = y[13];
	p->x[2][2] = x[14];
	p->y[2][2] = y[14];
	p->x[2][1] = x[15];
	p->y[2][1] = y[15];
	for (j = 0; j < nComps; ++j) {
	  p->color[0][0].c[j] = c[0][j];
	  p->color[0][1].c[j] = c[1][j];
	  p->color[1][1].c[j] = c[2][j];
	  p->color[1][0].c[j] = c[3][j];
	}
	break;
      case 1:
	p->x[0][0] = patchesA[nPatchesA-1].x[0][3];
	p->y[0][0] = patchesA[nPatchesA-1].y[0][3];
	p->x[0][1] = patchesA[nPatchesA-1].x[1][3];
	p->y[0][1] = patchesA[nPatchesA-1].y[1][3];
	p->x[0][2] = patchesA[nPatchesA-1].x[2][3];
	p->y[0][2] = patchesA[nPatchesA-1].y[2][3];
	p->x[0][3] = patchesA[nPatchesA-1].x[3][3];
	p->y[0][3] = patchesA[nPatchesA-1].y[3][3];
	p->x[1][3] = x[0];
	p->y[1][3] = y[0];
	p->x[2][3] = x[1];
	p->y[2][3] = y[1];
	p->x[3][3] = x[2];
	p->y[3][3] = y[2];
	p->x[3][2] = x[3];
	p->y[3][2] = y[3];
	p->x[3][1] = x[4];
	p->y[3][1] = y[4];
	p->x[3][0] = x[5];
	p->y[3][0] = y[5];
	p->x[2][0] = x[6];
	p->y[2][0] = y[6];
	p->x[1][0] = x[7];
	p->y[1][0] = y[7];
	p->x[1][1] = x[8];
	p->y[1][1] = y[8];
	p->x[1][2] = x[9];
	p->y[1][2] = y[9];
	p->x[2][2] = x[10];
	p->y[2][2] = y[10];
	p->x[2][1] = x[11];
	p->y[2][1] = y[11];
	for (j = 0; j < nComps; ++j) {
	  p->color[0][0].c[j] = patchesA[nPatchesA-1].color[0][1].c[j];
	  p->color[0][1].c[j] = patchesA[nPatchesA-1].color[1][1].c[j];
	  p->color[1][1].c[j] = c[0][j];
	  p->color[1][0].c[j] = c[1][j];
	}
	break;
      case 2:
	p->x[0][0] = patchesA[nPatchesA-1].x[3][3];
	p->y[0][0] = patchesA[nPatchesA-1].y[3][3];
	p->x[0][1] = patchesA[nPatchesA-1].x[3][2];
	p->y[0][1] = patchesA[nPatchesA-1].y[3][2];
	p->x[0][2] = patchesA[nPatchesA-1].x[3][1];
	p->y[0][2] = patchesA[nPatchesA-1].y[3][1];
	p->x[0][3] = patchesA[nPatchesA-1].x[3][0];
	p->y[0][3] = patchesA[nPatchesA-1].y[3][0];
	p->x[1][3] = x[0];
	p->y[1][3] = y[0];
	p->x[2][3] = x[1];
	p->y[2][3] = y[1];
	p->x[3][3] = x[2];
	p->y[3][3] = y[2];
	p->x[3][2] = x[3];
	p->y[3][2] = y[3];
	p->x[3][1] = x[4];
	p->y[3][1] = y[4];
	p->x[3][0] = x[5];
	p->y[3][0] = y[5];
	p->x[2][0] = x[6];
	p->y[2][0] = y[6];
	p->x[1][0] = x[7];
	p->y[1][0] = y[7];
	p->x[1][1] = x[8];
	p->y[1][1] = y[8];
	p->x[1][2] = x[9];
	p->y[1][2] = y[9];
	p->x[2][2] = x[10];
	p->y[2][2] = y[10];
	p->x[2][1] = x[11];
	p->y[2][1] = y[11];
	for (j = 0; j < nComps; ++j) {
	  p->color[0][0].c[j] = patchesA[nPatchesA-1].color[1][1].c[j];
	  p->color[0][1].c[j] = patchesA[nPatchesA-1].color[1][0].c[j];
	  p->color[1][1].c[j] = c[0][j];
	  p->color[1][0].c[j] = c[1][j];
	}
	break;
      case 3:
	p->x[0][0] = patchesA[nPatchesA-1].x[3][0];
	p->y[0][0] = patchesA[nPatchesA-1].y[3][0];
	p->x[0][1] = patchesA[nPatchesA-1].x[2][0];
	p->y[0][1] = patchesA[nPatchesA-1].y[2][0];
	p->x[0][2] = patchesA[nPatchesA-1].x[1][0];
	p->y[0][2] = patchesA[nPatchesA-1].y[1][0];
	p->x[0][3] = patchesA[nPatchesA-1].x[0][0];
	p->y[0][3] = patchesA[nPatchesA-1].y[0][0];
	p->x[1][3] = x[0];
	p->y[1][3] = y[0];
	p->x[2][3] = x[1];
	p->y[2][3] = y[1];
	p->x[3][3] = x[2];
	p->y[3][3] = y[2];
	p->x[3][2] = x[3];
	p->y[3][2] = y[3];
	p->x[3][1] = x[4];
	p->y[3][1] = y[4];
	p->x[3][0] = x[5];
	p->y[3][0] = y[5];
	p->x[2][0] = x[6];
	p->y[2][0] = y[6];
	p->x[1][0] = x[7];
	p->y[1][0] = y[7];
	p->x[1][1] = x[8];
	p->y[1][1] = y[8];
	p->x[1][2] = x[9];
	p->y[1][2] = y[9];
	p->x[2][2] = x[10];
	p->y[2][2] = y[10];
	p->x[2][1] = x[11];
	p->y[2][1] = y[11];
	for (j = 0; j < nComps; ++j) {
	  p->color[0][0].c[j] = patchesA[nPatchesA-1].color[1][0].c[j];
	  p->color[0][1].c[j] = patchesA[nPatchesA-1].color[0][0].c[j];
	  p->color[1][1].c[j] = c[0][j];
	  p->color[1][0].c[j] = c[1][j];
	}
	break;
      }
    }
    ++nPatchesA;
    bitBuf->flushBits();
  }
  delete bitBuf;

  if (typeA == 6) {
    for (i = 0; i < nPatchesA; ++i) {
      p = &patchesA[i];
      p->x[1][1] = (-4 * p->x[0][0]
		    +6 * (p->x[0][1] + p->x[1][0])
		    -2 * (p->x[0][3] + p->x[3][0])
		    +3 * (p->x[3][1] + p->x[1][3])
		    - p->x[3][3]) / 9;
      p->y[1][1] = (-4 * p->y[0][0]
		    +6 * (p->y[0][1] + p->y[1][0])
		    -2 * (p->y[0][3] + p->y[3][0])
		    +3 * (p->y[3][1] + p->y[1][3])
		    - p->y[3][3]) / 9;
      p->x[1][2] = (-4 * p->x[0][3]
		    +6 * (p->x[0][2] + p->x[1][3])
		    -2 * (p->x[0][0] + p->x[3][3])
		    +3 * (p->x[3][2] + p->x[1][0])
		    - p->x[3][0]) / 9;
      p->y[1][2] = (-4 * p->y[0][3]
		    +6 * (p->y[0][2] + p->y[1][3])
		    -2 * (p->y[0][0] + p->y[3][3])
		    +3 * (p->y[3][2] + p->y[1][0])
		    - p->y[3][0]) / 9;
      p->x[2][1] = (-4 * p->x[3][0]
		    +6 * (p->x[3][1] + p->x[2][0])
		    -2 * (p->x[3][3] + p->x[0][0])
		    +3 * (p->x[0][1] + p->x[2][3])
		    - p->x[0][3]) / 9;
      p->y[2][1] = (-4 * p->y[3][0]
		    +6 * (p->y[3][1] + p->y[2][0])
		    -2 * (p->y[3][3] + p->y[0][0])
		    +3 * (p->y[0][1] + p->y[2][3])
		    - p->y[0][3]) / 9;
      p->x[2][2] = (-4 * p->x[3][3]
		    +6 * (p->x[3][2] + p->x[2][3])
		    -2 * (p->x[3][0] + p->x[0][3])
		    +3 * (p->x[0][2] + p->x[2][0])
		    - p->x[0][0]) / 9;
      p->y[2][2] = (-4 * p->y[3][3]
		    +6 * (p->y[3][2] + p->y[2][3])
		    -2 * (p->y[3][0] + p->y[0][3])
		    +3 * (p->y[0][2] + p->y[2][0])
		    - p->y[0][0]) / 9;
    }
  }

  shading = new GfxPatchMeshShading(typeA, patchesA, nPatchesA,
				    funcsA, nFuncsA);
  if (!shading->init(dict)) {
    delete shading;
    return NULL;
  }
  return shading;

 err2:
  obj1.free();
 err1:
  return NULL;
}

Project: poppler
File: GfxState.cc

GBool GfxState::parseBlendMode(Object *obj, GfxBlendMode *mode) {
  Object obj2;
  int i, j;

  if (obj->isName()) {
    for (i = 0; i < nGfxBlendModeNames; ++i) {
      if (!strcmp(obj->getName(), gfxBlendModeNames[i].name)) {
	*mode = gfxBlendModeNames[i].mode;
	return gTrue;
      }
    }
    return gFalse;
  } else if (obj->isArray()) {
    for (i = 0; i < obj->arrayGetLength(); ++i) {
      obj->arrayGet(i, &obj2);
      if (!obj2.isName()) {
	obj2.free();
	return gFalse;
      }
      for (j = 0; j < nGfxBlendModeNames; ++j) {
	if (!strcmp(obj2.getName(), gfxBlendModeNames[j].name)) {
	  obj2.free();
	  *mode = gfxBlendModeNames[j].mode;
	  return gTrue;
	}
      }
      obj2.free();
    }
    *mode = gfxBlendNormal;
    return gTrue;
  } else {
    return gFalse;
  }
}

Project: poppler
File: GfxState.cc

void GfxICCBasedCache::put(int numA, int genA,
  GfxICCBasedColorSpace *cs)
{
  int i;

  if (cache[GFX_ICCBASED_CACHE_SIZE-1].num > 0) {
    delete cache[GFX_ICCBASED_CACHE_SIZE-1].colorSpace;
  }
  for (i = GFX_ICCBASED_CACHE_SIZE-1; i > 0; i--) {
    if (cache[i - 1].num > 0) cache[i] = cache[i - 1];
  }
  cache[0].num = numA;
  cache[0].gen = genA;
  cache[0].colorSpace = (GfxICCBasedColorSpace *)cs->copy();
}

Project: poppler
File: GfxState.cc

GfxState *GfxState::save() {
  GfxState *newState;

  newState = copy();
  newState->saved = this;
  return newState;
}

Project: poppler
File: GfxState.cc

void GfxState::setFillColorSpace(GfxColorSpace *colorSpace) {
  if (fillColorSpace) {
    delete fillColorSpace;
  }
  fillColorSpace = colorSpace;
}

Project: poppler
File: GfxState.cc

void GfxState::setFont(GfxFont *fontA, double fontSizeA) {
  if (font)
    font->decRefCnt();

  font = fontA;
  fontSize = fontSizeA;
}

Project: poppler
File: GfxState.cc

void GfxState::setLineDash(double *dash, int length, double start) {
  if (lineDash)
    gfree(lineDash);
  lineDash = dash;
  lineDashLength = length;
  lineDashStart = start;
}

Project: poppler
File: GfxState.cc

void GfxState::setPath(GfxPath *pathA) {
  delete path;
  path = pathA;
}

Project: poppler
File: GfxState.cc

void GfxState::setStrokeColorSpace(GfxColorSpace *colorSpace) {
  if (strokeColorSpace) {
    delete strokeColorSpace;
  }
  strokeColorSpace = colorSpace;
}

Project: poppler
File: GfxState.cc

void GfxState::setStrokePattern(GfxPattern *pattern) {
  if (strokePattern) {
    delete strokePattern;
  }
  strokePattern = pattern;
}

Project: poppler
File: GfxState.cc

void GfxState::setTransfer(Function **funcs) {
  int i;

  for (i = 0; i < 4; ++i) {
    if (transfer[i]) {
      delete transfer[i];
    }
    transfer[i] = funcs[i];
  }
}

Project: poppler

int GfxColorSpace::setupColorProfiles()
{
  static GBool initialized = gFalse;
  cmsHTRANSFORM transform;
  unsigned int nChannels;

  if (initialized) return 0;
  initialized = gTrue;

  cmsSetErrorHandler(CMSError);

  if (displayProfile == NULL) {
    if (displayProfileName == NULL) {
      displayProfile = loadColorProfile("display.icc");
    } else if (displayProfileName->getLength() > 0) {
      displayProfile = loadColorProfile(displayProfileName->getCString());
    }
  }
  RGBProfile = loadColorProfile("RGB.icc");
  if (RGBProfile == NULL) {
    /* use built in sRGB profile */
    RGBProfile = cmsCreate_sRGBProfile();
  }
  if (displayProfile != NULL) {
    displayPixelType = getCMSColorSpaceType(cmsGetColorSpace(displayProfile));
    nChannels = getCMSNChannels(cmsGetColorSpace(displayProfile));
    cmsHPROFILE XYZProfile = cmsCreateXYZProfile();
    if ((transform = cmsCreateTransform(XYZProfile, TYPE_XYZ_DBL,
	   displayProfile, 
	   COLORSPACE_SH(displayPixelType) |
	     CHANNELS_SH(nChannels) | BYTES_SH(1),
	  INTENT_RELATIVE_COLORIMETRIC,0)) == 0) {
      error(-1, "Can't create Lab transform");
    } else {
      XYZ2DisplayTransform = new GfxColorTransform(transform);
    }
    cmsCloseProfile(XYZProfile);
  }
  return 0;
}

Project: poppler
File: GfxState.cc

void GfxState::shift(double dx, double dy) {
  curX += dx;
  curY += dy;
}

Project: poppler
File: GfxState.cc

void GfxState::shiftCTM(double tx, double ty) {
  ctm[4] += tx;
  ctm[5] += ty;
  clipXMin += tx;
  clipYMin += ty;
  clipXMax += tx;
  clipYMax += ty;
}

Project: poppler
File: GfxState.cc

void GfxState::textShift(double tx, double ty) {
  double dx, dy;

  textTransformDelta(tx, ty, &dx, &dy);
  curX += dx;
  curY += dy;
}

Project: poppler
File: GfxState.cc

void Matrix::transform(double x, double y, double *tx, double *ty)
{
  double temp_x, temp_y;

  temp_x = m[0] * x + m[2] * y + m[4];
  temp_y = m[1] * x + m[3] * y + m[5];

  *tx = temp_x;
  *ty = temp_y;
}

Project: poppler
File: GfxState.cc

GfxAxialShading::~GfxAxialShading() {
  int i;

  for (i = 0; i < nFuncs; ++i) {
    delete funcs[i];
  }
}

Project: poppler
File: GfxState.cc

GfxCalGrayColorSpace::~GfxCalGrayColorSpace() {
}

Project: poppler
File: GfxState.cc

GfxCalRGBColorSpace::~GfxCalRGBColorSpace() {
}

Project: poppler
File: GfxState.cc

GfxColorSpace::~GfxColorSpace() {
}

Project: poppler
File: GfxState.cc

GfxDeviceCMYKColorSpace::~GfxDeviceCMYKColorSpace() {
}

Project: poppler
File: GfxState.cc

GfxDeviceGrayColorSpace::~GfxDeviceGrayColorSpace() {
}

Project: poppler
File: GfxState.cc

GfxDeviceNColorSpace::~GfxDeviceNColorSpace() {
  int i;

  for (i = 0; i < nComps; ++i) {
    delete names[i];
  }
  delete alt;
  delete func;
}

Project: poppler
File: GfxState.cc

GfxDeviceRGBColorSpace::~GfxDeviceRGBColorSpace() {
}

Project: poppler
File: GfxState.cc

GfxFunctionShading::~GfxFunctionShading() {
  int i;

  for (i = 0; i < nFuncs; ++i) {
    delete funcs[i];
  }
}

Project: poppler
File: GfxState.cc

GfxGouraudTriangleShading::~GfxGouraudTriangleShading() {
  int i;

  gfree(vertices);
  gfree(triangles);
  for (i = 0; i < nFuncs; ++i) {
    delete funcs[i];
  }
}

Project: poppler
File: GfxState.cc

GfxICCBasedColorSpace::~GfxICCBasedColorSpace() {
  delete alt;
#ifdef USE_CMS
  if (transform != NULL) {
    if (transform->unref() == 0) delete transform;
  }
  if (lineTransform != NULL) {
    if (lineTransform->unref() == 0) delete lineTransform;
  }
#endif
}

Project: poppler
File: GfxState.cc

GfxImageColorMap::~GfxImageColorMap() {
  int i;

  delete colorSpace;
  for (i = 0; i < gfxColorMaxComps; ++i) {
    gfree(lookup[i]);
  }
  gfree(byte_lookup);
}

Project: poppler
File: GfxState.cc

GfxIndexedColorSpace::~GfxIndexedColorSpace() {
  delete base;
  gfree(lookup);
}

Project: poppler
File: GfxState.cc

GfxLabColorSpace::~GfxLabColorSpace() {
}

Project: poppler
File: GfxState.cc

GfxPatchMeshShading::~GfxPatchMeshShading() {
  int i;

  gfree(patches);
  for (i = 0; i < nFuncs; ++i) {
    delete funcs[i];
  }
}

Project: poppler
File: GfxState.cc

GfxPath::~GfxPath() {
  int i;

  for (i = 0; i < n; ++i)
    delete subpaths[i];
  gfree(subpaths);
}

Project: poppler
File: GfxState.cc

GfxPattern::~GfxPattern() {
}

Project: poppler
File: GfxState.cc

GfxPatternColorSpace::~GfxPatternColorSpace() {
  if (under) {
    delete under;
  }
}

Project: poppler
File: GfxState.cc

GfxRadialShading::~GfxRadialShading() {
  int i;

  for (i = 0; i < nFuncs; ++i) {
    delete funcs[i];
  }
}

Project: poppler
File: GfxState.cc

GfxShading::~GfxShading() {
  if (colorSpace) {
    delete colorSpace;
  }
}

Project: poppler
File: GfxState.cc

GfxShadingBitBuf::~GfxShadingBitBuf() {
  str->close();
}

Project: poppler
File: GfxState.cc

GfxShadingPattern::~GfxShadingPattern() {
  delete shading;
}

Project: poppler
File: GfxState.cc

GfxSubpath::~GfxSubpath() {
  gfree(x);
  gfree(y);
  gfree(curve);
}

Project: poppler
File: JBIG2Stream.cc

JBIG2CodeTable::JBIG2CodeTable(Guint segNumA, JBIG2HuffmanTable *tableA):
  JBIG2Segment(segNumA)
{
  table = tableA;
}

Project: poppler
File: JBIG2Stream.cc

JBIG2HuffmanDecoder::JBIG2HuffmanDecoder() {
  str = NULL;
  reset();
}

Project: poppler
File: JBIG2Stream.cc

JBIG2MMRDecoder::JBIG2MMRDecoder() {
  str = NULL;
  reset();
}

Project: poppler
File: JBIG2Stream.cc

JBIG2PatternDict::JBIG2PatternDict(Guint segNumA, Guint sizeA):
  JBIG2Segment(segNumA)
{
  size = sizeA;
  bitmaps = (JBIG2Bitmap **)gmallocn(size, sizeof(JBIG2Bitmap *));
}

Project: poppler
File: JBIG2Stream.cc

  JBIG2Segment(Guint segNumA) { segNum = segNumA; }

Project: poppler
File: JBIG2Stream.cc

JBIG2Stream::JBIG2Stream(Stream *strA, Object *globalsStreamA):
  FilterStream(strA)
{
  pageBitmap = NULL;

  arithDecoder = new JArithmeticDecoder();
  genericRegionStats = new JArithmeticDecoderStats(1 << 1);
  refinementRegionStats = new JArithmeticDecoderStats(1 << 1);
  iadhStats = new JArithmeticDecoderStats(1 << 9);
  iadwStats = new JArithmeticDecoderStats(1 << 9);
  iaexStats = new JArithmeticDecoderStats(1 << 9);
  iaaiStats = new JArithmeticDecoderStats(1 << 9);
  iadtStats = new JArithmeticDecoderStats(1 << 9);
  iaitStats = new JArithmeticDecoderStats(1 << 9);
  iafsStats = new JArithmeticDecoderStats(1 << 9);
  iadsStats = new JArithmeticDecoderStats(1 << 9);
  iardxStats = new JArithmeticDecoderStats(1 << 9);
  iardyStats = new JArithmeticDecoderStats(1 << 9);
  iardwStats = new JArithmeticDecoderStats(1 << 9);
  iardhStats = new JArithmeticDecoderStats(1 << 9);
  iariStats = new JArithmeticDecoderStats(1 << 9);
  iaidStats = new JArithmeticDecoderStats(1 << 1);
  huffDecoder = new JBIG2HuffmanDecoder();
  mmrDecoder = new JBIG2MMRDecoder();

  globalsStreamA->copy(&globalsStream);
  segments = globalSegments = NULL;
  curStr = NULL;
  dataPtr = dataEnd = NULL;
}

Project: poppler
File: JBIG2Stream.cc

JBIG2SymbolDict::JBIG2SymbolDict(Guint segNumA, Guint sizeA):
  JBIG2Segment(segNumA)
{
  size = sizeA;
  bitmaps = (JBIG2Bitmap **)gmallocn(size, sizeof(JBIG2Bitmap *));
  genericRegionStats = NULL;
  refinementRegionStats = NULL;
}

Project: poppler

void JBIG2HuffmanDecoder::buildTable(JBIG2HuffmanTable *table, Guint len) {
  Guint i, j, k, prefix;
  JBIG2HuffmanTable tab;

  for (i = 0; i < len; ++i) {
    for (j = i; j < len && table[j].prefixLen == 0; ++j) ;
    if (j == len) {
      break;
    }
    for (k = j + 1; k < len; ++k) {
      if (table[k].prefixLen > 0 &&
	  table[k].prefixLen < table[j].prefixLen) {
	j = k;
      }
    }
    if (j != i) {
      tab = table[j];
      for (k = j; k > i; --k) {
	table[k] = table[k - 1];
      }
      table[i] = tab;
    }
  }
  table[i] = table[len];

  i = 0;
  prefix = 0;
  table[i++].prefix = prefix++;
  for (; table[i].rangeLen != jbig2HuffmanEOT; ++i) {
    prefix <<= table[i].prefixLen - table[i-1].prefixLen;
    table[i].prefix = prefix++;
  }
}

Project: poppler
File: JBIG2Stream.cc

  void clearPixel(int x, int y)
    { data[y * line + (x >> 3)] &= 0x7f7f >> (x & 7); }

Project: poppler
File: JBIG2Stream.cc

void JBIG2Bitmap::clearToOne() {
  memset(data, 0xff, h * line);
}

Project: poppler
File: JBIG2Stream.cc

void JBIG2Bitmap::clearToZero() {
  memset(data, 0, h * line);
}

Project: poppler
File: JBIG2Stream.cc

void JBIG2Stream::close() {
  if (pageBitmap) {
    delete pageBitmap;
    pageBitmap = NULL;
  }
  if (segments) {
    deleteGooList(segments, JBIG2Segment);
    segments = NULL;
  }
  if (globalSegments) {
    deleteGooList(globalSegments, JBIG2Segment);
    globalSegments = NULL;
  }
  dataPtr = dataEnd = NULL;
  FilterStream::close();
}

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 < 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
File: JBIG2Stream.cc

  JBIG2Bitmap *copy() { return new JBIG2Bitmap(0, this); }

Project: poppler
File: JBIG2Stream.cc

GBool JBIG2HuffmanDecoder::decodeInt(int *x, JBIG2HuffmanTable *table) {
  Guint i, len, prefix;

  i = 0;
  len = 0;
  prefix = 0;
  while (table[i].rangeLen != jbig2HuffmanEOT) {
    while (len < table[i].prefixLen) {
      prefix = (prefix << 1) | readBit();
      ++len;
    }
    if (prefix == table[i].prefix) {
      if (table[i].rangeLen == jbig2HuffmanOOB) {
	return gFalse;
      }
      if (table[i].rangeLen == jbig2HuffmanLOW) {
	*x = table[i].val - readBits(32);
      } else if (table[i].rangeLen > 0) {
	*x = table[i].val + readBits(table[i].rangeLen);
      } else {
	*x = table[i].val;
      }
      return gTrue;
    }
    ++i;
  }
  return gFalse;
}

Project: poppler
File: JBIG2Stream.cc

void JBIG2Bitmap::duplicateRow(int yDest, int ySrc) {
  memcpy(data + yDest * line, data + ySrc * line, line);
}

Project: poppler

void JBIG2Bitmap::expand(int newH, Guint pixel) {
  if (newH <= h || line <= 0 || newH >= (INT_MAX - 1) / line) {
    error(-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

JBIG2Segment *JBIG2Stream::findSegment(Guint segNum) {
  JBIG2Segment *seg;
  int i;

  for (i = 0; i < globalSegments->getLength(); ++i) {
    seg = (JBIG2Segment *)globalSegments->get(i);
    if (seg->getSegNum() == segNum) {
      return seg;
    }
  }
  for (i = 0; i < segments->getLength(); ++i) {
    seg = (JBIG2Segment *)segments->get(i);
    if (seg->getSegNum() == segNum) {
      return seg;
    }
  }
  return NULL;
}

Project: poppler
File: JBIG2Stream.cc

  JBIG2Bitmap *getBitmap(Guint idx) { return bitmaps[idx]; }

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);
      }
      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(str->getPos(), "Bad black code in JBIG2 MMR stream");
  --bufLen;
  return 1;
}

Project: poppler
File: JBIG2Stream.cc

int JBIG2Stream::getChar() {
  if (dataPtr && dataPtr < dataEnd) {
    return (*dataPtr++ ^ 0xff) & 0xff;
  }
  return EOF;
}

Project: poppler
File: JBIG2Stream.cc

  Guchar *getDataPtr() { return data; }

Project: poppler
File: JBIG2Stream.cc

  int getDataSize() { return h * line; }

Project: poppler
File: JBIG2Stream.cc

  JArithmeticDecoderStats *getGenericRegionStats()
    { return genericRegionStats; }

Project: poppler
File: JBIG2Stream.cc

  int getHeight() { return h; }

Project: poppler
File: JBIG2Stream.cc

  JBIG2HuffmanTable *getHuffTable() { return table; }

Project: poppler
File: JBIG2Stream.cc

  int getPixel(int x, int y)
    { return (x < 0 || x >= w || y < 0 || y >= h) ? 0 :
             (data[y * line + (x >> 3)] >> (7 - (x & 7))) & 1; }

Project: poppler
File: JBIG2Stream.cc

  JArithmeticDecoderStats *getRefinementRegionStats()
    { return refinementRegionStats; }

Project: poppler
File: JBIG2Stream.cc

  Guint getSegNum() { return segNum; }

Project: poppler
File: JBIG2Stream.cc

  Guint getSize() { return size; }

Project: poppler
File: JBIG2Stream.cc

  virtual JBIG2SegmentType getType() { return jbig2SegBitmap; }

Project: poppler
File: JBIG2Stream.cc

  virtual JBIG2SegmentType getType() { return jbig2SegSymbolDict; }

Project: poppler
File: JBIG2Stream.cc

  virtual JBIG2SegmentType getType() { return jbig2SegPatternDict; }

Project: poppler
File: JBIG2Stream.cc

  virtual JBIG2SegmentType getType() { return jbig2SegCodeTable; }

Project: poppler

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

  if (bufLen == 0) {
    buf = str->getChar() & 0xff;
    bufLen = 8;
    ++nBytesRead;
  }
  while (1) {
    if (bufLen >= 11 && ((buf >> (bufLen - 7)) & 0x7f) == 0) {
      if (bufLen <= 12) {
	code = buf << (12 - bufLen);
      } else {
	code = buf >> (bufLen - 12);
      }
      p = &whiteTab1[code & 0x1f];
    } else {
      if (bufLen <= 9) {
	code = buf << (9 - bufLen);
      } else {
	code = buf >> (bufLen - 9);
      }
      p = &whiteTab2[code & 0x1ff];
    }
    if (p->bits > 0 && p->bits <= (int)bufLen) {
      bufLen -= p->bits;
      return p->n;
    }
    if (bufLen >= 12) {
      break;
    }
    buf = (buf << 8) | (str->getChar() & 0xff);
    bufLen += 8;
    ++nBytesRead;
  }
  error(str->getPos(), "Bad white code in JBIG2 MMR stream");
  --bufLen;
  return 1;
}

Project: poppler
File: JBIG2Stream.cc

  int getWidth() { return w; }

Project: poppler
File: JBIG2Stream.cc

GBool JBIG2Stream::isBinary(GBool last) {
  return str->isBinary(gTrue);
}

Project: poppler
File: JBIG2Stream.cc

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

Project: poppler
File: JBIG2Stream.cc

int JBIG2Stream::lookChar() {
  if (dataPtr && dataPtr < dataEnd) {
    return (*dataPtr ^ 0xff) & 0xff;
  }
  return EOF;
}

Project: poppler
File: JBIG2Stream.cc

inline int JBIG2Bitmap::nextPixel(JBIG2BitmapPtr *ptr) {
  int pix;

  if (!ptr->p) {
    pix = 0;
  } else if (ptr->x < 0) {
    ++ptr->x;
    pix = 0;
  } else {
    pix = (*ptr->p >> ptr->shift) & 1;
    if (++ptr->x == w) {
      ptr->p = NULL;
    } else if (ptr->shift == 0) {
      ++ptr->p;
      ptr->shift = 7;
    } else {
      --ptr->shift;
    }
  }
  return pix;
}

Project: poppler
File: JBIG2Stream.cc

Guint JBIG2HuffmanDecoder::readBit() {
  if (bufLen == 0) {
    buf = str->getChar();
    bufLen = 8;
  }
  --bufLen;
  return (buf >> bufLen) & 1;
}

Project: poppler

GBool JBIG2Stream::readByte(int *x) {
 int c0;

  if ((c0 = curStr->getChar()) == EOF) {
    return gFalse;
  }
  *x = c0;
  if (c0 & 0x80) {
    *x |= -1 - 0xff;
  }
  return gTrue;
}

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(getPos(), "Unexpected EOF in JBIG2 stream");
}

Project: poppler

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

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

Project: poppler

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

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

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;
  JBIG2BitmapPtr cxPtr0 = {0}, cxPtr1 = {0};
  JBIG2BitmapPtr atPtr0 = {0}, atPtr1 = {0}, atPtr2 = {0}, atPtr3 = {0};
  int *refLine, *codingLine;
  int code1, code2, code3;
  int x, y, a0, pix, i, refI, codingI;

  bitmap = new JBIG2Bitmap(0, w, h);
  bitmap->clearToZero();


  if (mmr) {

    mmrDecoder->reset();
    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) {

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

      refI = 0;     // b1 = refLine[refI]
      codingI = 0;  // a1 = codingLine[codingI]
      a0 = 0;
      do {
	code1 = mmrDecoder->get2DCode();
	switch (code1) {
	case twoDimPass:
	  if (refLine[refI] < w) {
	    a0 = refLine[refI + 1];
	    refI += 2;
	  }
	  break;
	case twoDimHoriz:
	  if (codingI & 1) {
	    code1 = 0;
	    do {
	      code1 += code3 = mmrDecoder->getBlackCode();
	    } while (code3 >= 64);
	    code2 = 0;
	    do {
	      code2 += code3 = mmrDecoder->getWhiteCode();
	    } while (code3 >= 64);
	  } else {
	    code1 = 0;
	    do {
	      code1 += code3 = mmrDecoder->getWhiteCode();
	    } while (code3 >= 64);
	    code2 = 0;
	    do {
	      code2 += code3 = mmrDecoder->getBlackCode();
	    } while (code3 >= 64);
	  }
	  if (code1 > 0 || code2 > 0) {
	    a0 = codingLine[codingI++] = a0 + code1;
	    a0 = codingLine[codingI++] = a0 + code2;
	    while (refLine[refI] <= a0 && refLine[refI] < w) {
	      refI += 2;
	    }
	  }
	  break;
	case twoDimVert0:
	  a0 = codingLine[codingI++] = refLine[refI];
	  if (refLine[refI] < w) {
	    ++refI;
	  }
	  break;
	case twoDimVertR1:
	  a0 = codingLine[codingI++] = refLine[refI] + 1;
	  if (refLine[refI] < w) {
	    ++refI;
	    while (refLine[refI] <= a0 && refLine[refI] < w) {
	      refI += 2;
	    }
	  }
	  break;
	case twoDimVertR2:
	  a0 = codingLine[codingI++] = refLine[refI] + 2;
	  if (refLine[refI] < w) {
	    ++refI;
	    while (refLine[refI] <= a0 && refLine[refI] < w) {
	      refI += 2;
	    }
	  }
	  break;
	case twoDimVertR3:
	  a0 = codingLine[codingI++] = refLine[refI] + 3;
	  if (refLine[refI] < w) {
	    ++refI;
	    while (refLine[refI] <= a0 && refLine[refI] < w) {
	      refI += 2;
	    }
	  }
	  break;
	case twoDimVertL1:
	  a0 = codingLine[codingI++] = refLine[refI] - 1;
	  if (refI > 0) {
	    --refI;
	  } else {
	    ++refI;
	  }
	  while (refLine[refI] <= a0 && refLine[refI] < w) {
	    refI += 2;
	  }
	  break;
	case twoDimVertL2:
	  a0 = codingLine[codingI++] = refLine[refI] - 2;
	  if (refI > 0) {
	    --refI;
	  } else {
	    ++refI;
	  }
	  while (refLine[refI] <= a0 && refLine[refI] < w) {
	    refI += 2;
	  }
	  break;
	case twoDimVertL3:
	  a0 = codingLine[codingI++] = refLine[refI] - 3;
	  if (refI > 0) {
	    --refI;
	  } else {
	    ++refI;
	  }
	  while (refLine[refI] <= a0 && refLine[refI] < w) {
	    refI += 2;
	  }
	  break;
	default:
	  error(getPos(), "Illegal code in JBIG2 MMR bitmap data");
	  break;
	}
      } while (a0 < w);
      codingLine[codingI++] = w;

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

    if (mmrDataLength >= 0) {
      mmrDecoder->skipTo(mmrDataLength);
    } else {
      if (mmrDecoder->get24Bits() != 0x001001) {
	error(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) {
	  bitmap->duplicateRow(y, y-1);
	  continue;
	}
      }

      switch (templ) {
      case 0:

	bitmap->getPixelPtr(0, y-2, &cxPtr0);
	cx0 = bitmap->nextPixel(&cxPtr0);
	cx0 = (cx0 << 1) | bitmap->nextPixel(&cxPtr0);
	bitmap->getPixelPtr(0, y-1, &cxPtr1);
	cx1 = bitmap->nextPixel(&cxPtr1);
	cx1 = (cx1 << 1) | bitmap->nextPixel(&cxPtr1);
	cx1 = (cx1 << 1) | bitmap->nextPixel(&cxPtr1);
	cx2 = 0;
	bitmap->getPixelPtr(atx[0], y + aty[0], &atPtr0);
	bitmap->getPixelPtr(atx[1], y + aty[1], &atPtr1);
	bitmap->getPixelPtr(atx[2], y + aty[2], &atPtr2);
	bitmap->getPixelPtr(atx[3], y + aty[3], &atPtr3);

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

	  cx = (cx0 << 13) | (cx1 << 8) | (cx2 << 4) |
	       (bitmap->nextPixel(&atPtr0) << 3) |
	       (bitmap->nextPixel(&atPtr1) << 2) |
	       (bitmap->nextPixel(&atPtr2) << 1) |
	       bitmap->nextPixel(&atPtr3);

	  if (useSkip && skip->getPixel(x, y)) {
	    pix = 0;

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

	  cx0 = ((cx0 << 1) | bitmap->nextPixel(&cxPtr0)) & 0x07;
	  cx1 = ((cx1 << 1) | bitmap->nextPixel(&cxPtr1)) & 0x1f;
	  cx2 = ((cx2 << 1) | pix) & 0x0f;
	}
	break;

      case 1:

	bitmap->getPixelPtr(0, y-2, &cxPtr0);
	cx0 = bitmap->nextPixel(&cxPtr0);
	cx0 = (cx0 << 1) | bitmap->nextPixel(&cxPtr0);
	cx0 = (cx0 << 1) | bitmap->nextPixel(&cxPtr0);
	bitmap->getPixelPtr(0, y-1, &cxPtr1);
	cx1 = bitmap->nextPixel(&cxPtr1);
	cx1 = (cx1 << 1) | bitmap->nextPixel(&cxPtr1);
	cx1 = (cx1 << 1) | bitmap->nextPixel(&cxPtr1);
	cx2 = 0;
	bitmap->getPixelPtr(atx[0], y + aty[0], &atPtr0);

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

	  cx = (cx0 << 9) | (cx1 << 4) | (cx2 << 1) |
	       bitmap->nextPixel(&atPtr0);

	  if (useSkip && skip->getPixel(x, y)) {
	    pix = 0;

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

	  cx0 = ((cx0 << 1) | bitmap->nextPixel(&cxPtr0)) & 0x0f;
	  cx1 = ((cx1 << 1) | bitmap->nextPixel(&cxPtr1)) & 0x1f;
	  cx2 = ((cx2 << 1) | pix) & 0x07;
	}
	break;

      case 2:

	bitmap->getPixelPtr(0, y-2, &cxPtr0);
	cx0 = bitmap->nextPixel(&cxPtr0);
	cx0 = (cx0 << 1) | bitmap->nextPixel(&cxPtr0);
	bitmap->getPixelPtr(0, y-1, &cxPtr1);
	cx1 = bitmap->nextPixel(&cxPtr1);
	cx1 = (cx1 << 1) | bitmap->nextPixel(&cxPtr1);
	cx2 = 0;
	bitmap->getPixelPtr(atx[0], y + aty[0], &atPtr0);

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

	  cx = (cx0 << 7) | (cx1 << 3) | (cx2 << 1) |
	       bitmap->nextPixel(&atPtr0);

	  if (useSkip && skip->getPixel(x, y)) {
	    pix = 0;

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

	  cx0 = ((cx0 << 1) | bitmap->nextPixel(&cxPtr0)) & 0x07;
	  cx1 = ((cx1 << 1) | bitmap->nextPixel(&cxPtr1)) & 0x0f;
	  cx2 = ((cx2 << 1) | pix) & 0x03;
	}
	break;

      case 3:

	bitmap->getPixelPtr(0, y-1, &cxPtr1);
	cx1 = bitmap->nextPixel(&cxPtr1);
	cx1 = (cx1 << 1) | bitmap->nextPixel(&cxPtr1);
	cx2 = 0;
	bitmap->getPixelPtr(atx[0], y + aty[0], &atPtr0);

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

	  cx = (cx1 << 5) | (cx2 << 1) |
	       bitmap->nextPixel(&atPtr0);

	  if (useSkip && skip->getPixel(x, y)) {
	    pix = 0;

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

	  cx1 = ((cx1 << 1) | bitmap->nextPixel(&cxPtr1)) & 0x1f;
	  cx2 = ((cx2 << 1) | pix) & 0x0f;
	}
	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);
      }

      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);
      }

      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::readGenericRefinementRegionSeg(Guint segNum, GBool imm,
						 GBool lossless, Guint length,
						 Guint *refSegs,
						 Guint nRefSegs) {
  JBIG2Bitmap *bitmap, *refBitmap;
  Guint w, h, x, y, segInfoFlags, extCombOp;
  Guint flags, templ, tpgrOn;
  int atx[2], aty[2];
  JBIG2Segment *seg;

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

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

  if (!templ) {
    if (!readByte(&atx[0]) || !readByte(&aty[0]) ||
	!readByte(&atx[1]) || !readByte(&aty[1])) {
      goto eofError;
    }
  }

  if (nRefSegs == 0 || imm) {
    if (pageH == 0xffffffff && y + h > curPageH) {
      pageBitmap->expand(y + h, pageDefPixel);
    }
  }

  if (nRefSegs > 1) {
    error(getPos(), "Bad reference in JBIG2 generic refinement segment");
    return;
  }
  if (nRefSegs == 1) {
    seg = findSegment(refSegs[0]);
    if (seg == NULL || seg->getType() != jbig2SegBitmap) {
      error(getPos(), "Bad bitmap reference in JBIG2 generic refinement segment");
      return;
    }
    refBitmap = (JBIG2Bitmap *)seg;
  } else {
    refBitmap = pageBitmap->getSlice(x, y, w, h);
  }

  resetRefinementStats(templ, NULL);
  arithDecoder->start();

  bitmap = readGenericRefinementRegion(w, h, templ, tpgrOn,
				       refBitmap, 0, 0, atx, aty);

  if (imm) {
    pageBitmap->combine(bitmap, x, y, extCombOp);
    delete bitmap;

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

  if (nRefSegs == 1) {
    discardSegment(refSegs[0]);
  } else {
    delete refBitmap;
  }

  return;

 eofError:
  error(getPos(), "Unexpected EOF in JBIG2 stream");
}

Project: poppler

void JBIG2Stream::readGenericRegionSeg(Guint segNum, GBool imm,
				       GBool lossless, Guint length) {
  JBIG2Bitmap *bitmap;
  Guint w, h, x, y, segInfoFlags, extCombOp;
  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 ? 0 : length - 18);

  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);
  }

  return;

 eofError:
  error(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(getPos(), "Bad bitmap size in JBIG2 halftone segment");
    return;
  }
  if (gridH == 0 || gridW >= INT_MAX / gridH) {
    error(getPos(), "Bad grid size in JBIG2 halftone segment");
    return;
  }

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

  patternDict = (JBIG2PatternDict *)seg;
  bpp = 0;
  i = 1;
  while (i < patternDict->getSize()) {
    ++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]);
	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(getPos(), "Unexpected EOF in JBIG2 stream");
}

Project: poppler

GBool JBIG2Stream::readLong(int *x) {
  int c0, c1, c2, c3;

  if ((c0 = curStr->getChar()) == EOF ||
      (c1 = curStr->getChar()) == EOF ||
      (c2 = curStr->getChar()) == EOF ||
      (c3 = curStr->getChar()) == EOF) {
    return gFalse;
  }
  *x = ((c0 << 24) | (c1 << 16) | (c2 << 8) | c3);
  if (c0 & 0x80) {
    *x |= -1 - (int)0xffffffff;
  }
  return gTrue;
}

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 (pageDefPixel) {
    pageBitmap->clearToOne();
  } else {
    pageBitmap->clearToZero();
  }

  return;

 eofError:
  error(getPos(), "Unexpected EOF in JBIG2 stream");
}

Project: poppler

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

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

Project: poppler

void JBIG2Stream::readSegments() {
  Guint segNum, segFlags, segType, page, segLength;
  Guint refFlags, nRefSegs;
  Guint *refSegs;
  int segDataPos;
  int c1, c2, c3;
  Guint i;

  while (readULong(&segNum)) {

    if (!readUByte(&segFlags)) {
      goto eofError1;
    }
    segType = segFlags & 0x3f;

    if (!readUByte(&refFlags)) {
      goto eofError1;
    }
    nRefSegs = refFlags >> 5;
    if (nRefSegs == 7) {
      if ((c1 = curStr->getChar()) == EOF ||
	  (c2 = curStr->getChar()) == EOF ||
	  (c3 = curStr->getChar()) == EOF) {
	goto eofError1;
      }
      refFlags = (refFlags << 24) | (c1 << 16) | (c2 << 8) | c3;
      nRefSegs = refFlags & 0x1fffffff;
      for (i = 0; i < (nRefSegs + 9) >> 3; ++i) {
	c1 = curStr->getChar();
      }
    }

    refSegs = (Guint *)gmallocn(nRefSegs, sizeof(Guint));
    if (segNum <= 256) {
      for (i = 0; i < nRefSegs; ++i) {
	if (!readUByte(&refSegs[i])) {
	  goto eofError2;
	}
      }
    } else if (segNum <= 65536) {
      for (i = 0; i < nRefSegs; ++i) {
	if (!readUWord(&refSegs[i])) {
	  goto eofError2;
	}
      }
    } else {
      for (i = 0; i < nRefSegs; ++i) {
	if (!readULong(&refSegs[i])) {
	  goto eofError2;
	}
      }
    }

    if (segFlags & 0x40) {
      if (!readULong(&page)) {
	goto eofError2;
      }
    } else {
      if (!readUByte(&page)) {
	goto eofError2;
      }
    }

    if (!readULong(&segLength)) {
      goto eofError2;
    }

    segDataPos = getPos();

    switch (segType) {
    case 0:
      if (!readSymbolDictSeg(segNum, segLength, refSegs, nRefSegs)) {
	goto syntaxError;
      }
      break;
    case 4:
      readTextRegionSeg(segNum, gFalse, gFalse, segLength, refSegs, nRefSegs);
      break;
    case 6:
      readTextRegionSeg(segNum, gTrue, gFalse, segLength, refSegs, nRefSegs);
      break;
    case 7:
      readTextRegionSeg(segNum, gTrue, gTrue, segLength, refSegs, nRefSegs);
      break;
    case 16:
      readPatternDictSeg(segNum, segLength);
      break;
    case 20:
      readHalftoneRegionSeg(segNum, gFalse, gFalse, segLength,
			    refSegs, nRefSegs);
      break;
    case 22:
      readHalftoneRegionSeg(segNum, gTrue, gFalse, segLength,
			    refSegs, nRefSegs);
      break;
    case 23:
      readHalftoneRegionSeg(segNum, gTrue, gTrue, segLength,
			    refSegs, nRefSegs);
      break;
    case 36:
      readGenericRegionSeg(segNum, gFalse, gFalse, segLength);
      break;
    case 38:
      readGenericRegionSeg(segNum, gTrue, gFalse, segLength);
      break;
    case 39:
      readGenericRegionSeg(segNum, gTrue, gTrue, segLength);
      break;
    case 40:
      readGenericRefinementRegionSeg(segNum, gFalse, gFalse, segLength,
				     refSegs, nRefSegs);
      break;
    case 42:
      readGenericRefinementRegionSeg(segNum, gTrue, gFalse, segLength,
				     refSegs, nRefSegs);
      break;
    case 43:
      readGenericRefinementRegionSeg(segNum, gTrue, gTrue, segLength,
				     refSegs, nRefSegs);
      break;
    case 48:
      readPageInfoSeg(segLength);
      break;
    case 50:
      readEndOfStripeSeg(segLength);
      break;
    case 52:
      readProfilesSeg(segLength);
      break;
    case 53:
      readCodeTableSeg(segNum, segLength);
      break;
    case 62:
      readExtensionSeg(segLength);
      break;
    default:
      error(getPos(), "Unknown segment type in JBIG2 stream");
      for (i = 0; i < segLength; ++i) {
	if ((c1 = curStr->getChar()) == EOF) {
	  goto eofError2;
	}
      }
      break;
    }


    if (segLength != 0xffffffff) {

      int segExtraBytes = segDataPos + segLength - getPos();
      if (segExtraBytes > 0) {

	
	
	error(getPos(), "%d extraneous byte%s after segment",
	      segExtraBytes, (segExtraBytes > 1) ? "s" : "");
	
	
	int trash;
	for (int i = segExtraBytes; i > 0; i--) {
	  readByte(&trash);
	}
	
      } else if (segExtraBytes < 0) {
	
	
	error(getPos(), "Previous segment handler read too many bytes");
	
      }

    }
    
    gfree(refSegs);
  }

  return;

 syntaxError:
  gfree(refSegs);
  return;

 eofError2:
  gfree(refSegs);
 eofError1:
  error(getPos(), "Unexpected EOF in JBIG2 stream");
}

Project: poppler
File: PSOutputDev.cc

DeviceNRecoder::DeviceNRecoder(Stream *strA, int widthA, int heightA,
			       GfxImageColorMap *colorMapA):
    FilterStream(strA) {
  width = widthA;
  height = heightA;
  colorMap = colorMapA;
  imgStr = NULL;
  pixelIdx = 0;
  bufIdx = gfxColorMaxComps;
  bufSize = ((GfxDeviceNColorSpace *)colorMap->getColorSpace())->
              getAlt()->getNComps();
  func = ((GfxDeviceNColorSpace *)colorMap->getColorSpace())->
           getTintTransformFunc();
}

Project: poppler
File: PSOutputDev.cc

PSOutCustomColor::PSOutCustomColor(double cA, double mA,
				   double yA, double kA, GooString *nameA) {
  c = cA;
  m = mA;
  y = yA;
  k = kA;
  name = nameA;
  next = NULL;
}

Project: poppler

PSOutputDev::PSOutputDev(const char *fileName, XRef *xrefA, Catalog *catalog,
			 char *psTitle,
			 int firstPage, int lastPage, PSOutMode modeA,
			 int paperWidthA, int paperHeightA, GBool duplexA,
			 int imgLLXA, int imgLLYA, int imgURXA, int imgURYA,
			 GBool forceRasterizeA,
			 GBool manualCtrlA) {
  FILE *f;
  PSFileType fileTypeA;

  underlayCbk = NULL;
  underlayCbkData = NULL;
  overlayCbk = NULL;
  overlayCbkData = NULL;

  fontIDs = NULL;
  fontFileIDs = NULL;
  fontFileNames = NULL;
  font8Info = NULL;
  font16Enc = NULL;
  imgIDs = NULL;
  formIDs = NULL;
  xobjStack = NULL;
  embFontList = NULL;
  customColors = NULL;
  haveTextClip = gFalse;
  t3String = NULL;

  forceRasterize = forceRasterizeA;

  if (!strcmp(fileName, "-")) {
    fileTypeA = psStdout;
    f = stdout;
  } else if (fileName[0] == '|') {
    fileTypeA = psPipe;
#ifdef HAVE_POPEN
#ifndef WIN32
    signal(SIGPIPE, (SignalFunc)SIG_IGN);
#endif
    if (!(f = popen(fileName + 1, "w"))) {
      error(-1, "Couldn't run print command '%s'", fileName);
      ok = gFalse;
      return;
    }
#else
    error(-1, "Print commands are not supported ('%s')", fileName);
    ok = gFalse;
    return;
#endif
  } else {
    fileTypeA = psFile;
    if (!(f = fopen(fileName, "w"))) {
      error(-1, "Couldn't open PostScript file '%s'", fileName);
      ok = gFalse;
      return;
    }
  }

  init(outputToFile, f, fileTypeA, psTitle,
       xrefA, catalog, firstPage, lastPage, modeA,
       imgLLXA, imgLLYA, imgURXA, imgURYA, manualCtrlA,
       paperWidthA, paperHeightA, duplexA);
}

Project: poppler
File: PSOutputDev.cc

void PSOutputDev::addCustomColor(GfxSeparationColorSpace *sepCS) {
  PSOutCustomColor *cc;
  GfxColor color;
  GfxCMYK cmyk;

  for (cc = customColors; cc; cc = cc->next) {
    if (!cc->name->cmp(sepCS->getName())) {
      return;
    }
  }
  color.c[0] = gfxColorComp1;
  sepCS->getCMYK(&color, &cmyk);
  cc = new PSOutCustomColor(colToDbl(cmyk.c), colToDbl(cmyk.m),
			    colToDbl(cmyk.y), colToDbl(cmyk.k),
			    sepCS->getName()->copy());
  cc->next = customColors;
  customColors = cc;
}

Project: poppler
File: PSOutputDev.cc

void PSOutputDev::addProcessColor(double c, double m, double y, double k) {
  if (c > 0) {
    processColors |= psProcessCyan;
  }
  if (m > 0) {
    processColors |= psProcessMagenta;
  }
  if (y > 0) {
    processColors |= psProcessYellow;
  }
  if (k > 0) {
    processColors |= psProcessBlack;
  }
}

Project: poppler

GBool PSOutputDev::axialShadedFill(GfxState *state, GfxAxialShading *shading) {
  double xMin, yMin, xMax, yMax;
  double x0, y0, x1, y1, dx, dy, mul;
  double tMin, tMax, t, t0, t1;
  int i;

  if (level == psLevel2Sep || level == psLevel3Sep) {
    if (shading->getColorSpace()->getMode() != csDeviceCMYK) {
      return gFalse;
    }
    processColors |= psProcessCMYK;
  }

  state->getUserClipBBox(&xMin, &yMin, &xMax, &yMax);

  shading->getCoords(&x0, &y0, &x1, &y1);
  dx = x1 - x0;
  dy = y1 - y0;
  if (fabs(dx) < 0.01 && fabs(dy) < 0.01) {
    return gTrue;
  } else {
    mul = 1 / (dx * dx + dy * dy);
    tMin = tMax = ((xMin - x0) * dx + (yMin - y0) * dy) * mul;
    t = ((xMin - x0) * dx + (yMax - y0) * dy) * mul;
    if (t < tMin) {
      tMin = t;
    } else if (t > tMax) {
      tMax = t;
    }
    t = ((xMax - x0) * dx + (yMin - y0) * dy) * mul;
    if (t < tMin) {
      tMin = t;
    } else if (t > tMax) {
      tMax = t;
    }
    t = ((xMax - x0) * dx + (yMax - y0) * dy) * mul;
    if (t < tMin) {
      tMin = t;
    } else if (t > tMax) {
      tMax = t;
    }
    if (tMin < 0 && !shading->getExtend0()) {
      tMin = 0;
    }
    if (tMax > 1 && !shading->getExtend1()) {
      tMax = 1;
    }
  }

  t0 = shading->getDomain0();
  t1 = shading->getDomain1();

  writePSFmt("/t0 {0:.4g} def\n", t0);
  writePSFmt("/t1 {0:.4g} def\n", t1);
  writePSFmt("/dt {0:.4g} def\n", t1 - t0);
  writePSFmt("/x0 {0:.4g} def\n", x0);
  writePSFmt("/y0 {0:.4g} def\n", y0);
  writePSFmt("/dx {0:.4g} def\n", x1 - x0);
  writePSFmt("/x1 {0:.4g} def\n", x1);
  writePSFmt("/y1 {0:.4g} def\n", y1);
  writePSFmt("/dy {0:.4g} def\n", y1 - y0);
  writePSFmt("/xMin {0:.4g} def\n", xMin);
  writePSFmt("/yMin {0:.4g} def\n", yMin);
  writePSFmt("/xMax {0:.4g} def\n", xMax);
  writePSFmt("/yMax {0:.4g} def\n", yMax);
  writePSFmt("/n {0:d} def\n", shading->getColorSpace()->getNComps());
  if (shading->getNFuncs() == 1) {
    writePS("/func ");
    cvtFunction(shading->getFunc(0));
    writePS("def\n");
  } else {
    writePS("/func {\n");
    for (i = 0; i < shading->getNFuncs(); ++i) {
      if (i < shading->getNFuncs() - 1) {
	writePS("dup\n");
      }
      cvtFunction(shading->getFunc(i));
      writePS("exec\n");
      if (i < shading->getNFuncs() - 1) {
	writePS("exch\n");
      }
    }
    writePS("} def\n");
  }
  writePSFmt("{0:.4g} {1:.4g} 0 axialSH\n", tMin, tMax);

  return gTrue;
}

Project: poppler
File: PSOutputDev.cc

void PSOutputDev::clip(GfxState *state) {
  doPath(state->getPath());
  writePS("W\n");
}

Project: poppler
File: PSOutputDev.cc

void PSOutputDev::clipToStrokePath(GfxState *state) {
  doPath(state->getPath());
  writePS("Ws\n");
}