Index: poppler/CairoOutputDev.cc =================================================================== RCS file: /cvs/poppler/poppler/poppler/CairoOutputDev.cc,v retrieving revision 1.28 diff -u -r1.28 CairoOutputDev.cc --- poppler/CairoOutputDev.cc 16 Feb 2006 19:41:17 -0000 1.28 +++ poppler/CairoOutputDev.cc 18 Feb 2006 18:44:36 -0000 @@ -552,6 +552,105 @@ delete imgStr; } +void CairoOutputDev::drawSoftMaskedImage(GfxState *state, Object *ref, Stream *str, + int width, int height, + GfxImageColorMap *colorMap, + Stream *maskStr, + int maskWidth, int maskHeight, + GfxImageColorMap *maskColorMap) +{ + ImageStream *maskImgStr; + maskImgStr = new ImageStream(maskStr, maskWidth, + maskColorMap->getNumPixelComps(), + maskColorMap->getBits()); + maskImgStr->reset(); + + unsigned char *maskBuffer; + maskBuffer = (unsigned char *)gmalloc (maskWidth * maskHeight * 4); + unsigned char *maskDest; + cairo_surface_t *maskImage; + cairo_pattern_t *maskPattern; + Guchar *pix; + int x, y; + for (y = 0; y < maskHeight; y++) { + maskDest = (unsigned char *) (maskBuffer + y * 4 * maskWidth); + pix = maskImgStr->getLine(); + maskColorMap->getGrayLine (pix, maskDest, maskWidth); + } + + maskImage = cairo_image_surface_create_for_data (maskBuffer, CAIRO_FORMAT_A8, + maskWidth, maskHeight, maskWidth * 4); + + delete maskImgStr; + maskStr->close(); + unsigned char *buffer; + unsigned int *dest; + cairo_surface_t *image; + cairo_pattern_t *pattern; + ImageStream *imgStr; + GfxRGB rgb; + int alpha, i; + double *ctm; + cairo_matrix_t matrix; + int is_identity_transform; + + buffer = (unsigned char *)gmalloc (width * height * 4); + + /* TODO: Do we want to cache these? */ + imgStr = new ImageStream(str, width, + colorMap->getNumPixelComps(), + colorMap->getBits()); + imgStr->reset(); + + /* ICCBased color space doesn't do any color correction + * so check its underlying color space as well */ + is_identity_transform = colorMap->getColorSpace()->getMode() == csDeviceRGB || + colorMap->getColorSpace()->getMode() == csICCBased && + ((GfxICCBasedColorSpace*)colorMap->getColorSpace())->getAlt()->getMode() == csDeviceRGB; + + for (y = 0; y < height; y++) { + dest = (unsigned int *) (buffer + y * 4 * width); + pix = imgStr->getLine(); + colorMap->getRGBLine (pix, dest, width); + } + + image = cairo_image_surface_create_for_data (buffer, CAIRO_FORMAT_RGB24, + width, height, width * 4); + + if (image == NULL) + return; + pattern = cairo_pattern_create_for_surface (image); + maskPattern = cairo_pattern_create_for_surface (maskImage); + 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_matrix (maskPattern, &matrix); + + cairo_pattern_set_filter (pattern, CAIRO_FILTER_BILINEAR); + cairo_set_source (cairo, pattern); + cairo_mask (cairo, maskPattern); + + cairo_pattern_destroy (maskPattern); + cairo_surface_destroy (maskImage); + cairo_pattern_destroy (pattern); + cairo_surface_destroy (image); + free (buffer); + free (maskBuffer); + delete imgStr; +} void CairoOutputDev::drawImage(GfxState *state, Object *ref, Stream *str, int width, int height, GfxImageColorMap *colorMap, Index: poppler/CairoOutputDev.h =================================================================== RCS file: /cvs/poppler/poppler/poppler/CairoOutputDev.h,v retrieving revision 1.11 diff -u -r1.11 CairoOutputDev.h --- poppler/CairoOutputDev.h 10 Jan 2006 17:55:59 -0000 1.11 +++ poppler/CairoOutputDev.h 18 Feb 2006 18:44:36 -0000 @@ -117,6 +117,12 @@ virtual void drawImage(GfxState *state, Object *ref, Stream *str, int width, int height, GfxImageColorMap *colorMap, int *maskColors, GBool inlineImg); + virtual void drawSoftMaskedImage(GfxState *state, Object *ref, Stream *str, + int width, int height, + GfxImageColorMap *colorMap, + Stream *maskStr, + int maskWidth, int maskHeight, + GfxImageColorMap *maskColorMap); //----- Type 3 font operators virtual void type3D0(GfxState *state, double wx, double wy); Index: poppler/GfxState.cc =================================================================== RCS file: /cvs/poppler/poppler/poppler/GfxState.cc,v retrieving revision 1.9 diff -u -r1.9 GfxState.cc --- poppler/GfxState.cc 18 Jan 2006 22:32:13 -0000 1.9 +++ poppler/GfxState.cc 18 Feb 2006 18:44:39 -0000 @@ -205,6 +205,23 @@ } } +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); + } +} + + //------------------------------------------------------------------------ // GfxDeviceGrayColorSpace //------------------------------------------------------------------------ @@ -3434,6 +3451,39 @@ } } +void GfxImageColorMap::getGrayLine(Guchar *in, Guchar *out, int length) { + GfxColor color; + double *p; + int i, j; + Guchar *inp, *outp, *tmp_line; + GfxColorSpace *base; + + switch (colorSpace->getMode()) { + case csIndexed: + case csSeparation: + tmp_line = (Guchar *) gmalloc (length * nComps2); + for (i = 0; i < length; i++) { + for (j = 0; j < nComps2; j++) { + tmp_line[i * nComps2 + j] = byte_lookup[in[i] * nComps2 + j]; + } + } + colorSpace2->getGrayLine(tmp_line, out, length); + gfree (tmp_line); + break; + + default: + inp = in; + for (j = 0; j < length; j++) + for (i = 0; i < nComps; i++) { + *inp = byte_lookup[*inp * nComps + i]; + inp++; + } + colorSpace->getGrayLine(in, out, length); + break; + } + +} + void GfxImageColorMap::getRGBLine(Guchar *in, unsigned int *out, int length) { GfxColor color; double *p; Index: poppler/GfxState.h =================================================================== RCS file: /cvs/poppler/poppler/poppler/GfxState.h,v retrieving revision 1.4 diff -u -r1.4 GfxState.h --- poppler/GfxState.h 30 Oct 2005 20:29:05 -0000 1.4 +++ poppler/GfxState.h 18 Feb 2006 18:44:40 -0000 @@ -151,6 +151,7 @@ virtual void getRGB(GfxColor *color, GfxRGB *rgb) = 0; virtual void getCMYK(GfxColor *color, GfxCMYK *cmyk) = 0; virtual void getRGBLine(Guchar *in, unsigned int *out, int length); + virtual void getGrayLine(Guchar *in, Guchar *out, int length); // Return the number of color components. virtual int getNComps() = 0; @@ -869,6 +870,7 @@ void getGray(Guchar *x, GfxGray *gray); void getRGB(Guchar *x, GfxRGB *rgb); void getRGBLine(Guchar *in, unsigned int *out, int length); + void getGrayLine(Guchar *in, Guchar *out, int length); void getCMYK(Guchar *x, GfxCMYK *cmyk); void getColor(Guchar *x, GfxColor *color);