summaryrefslogtreecommitdiff
path: root/poppler
diff options
context:
space:
mode:
authorJeff Muizelaar <jeff@infidigm.net>2006-02-18 20:17:00 +0000
committerJeff Muizelaar <jeff@infidigm.net>2006-02-18 20:17:00 +0000
commit7c5c1361045429a429a6f40d936f8c7c01fe0d07 (patch)
treeed529eb1d7da287a8378300d69579b2a81c610f2 /poppler
parentdcb748f68112bd5f99fea8a3da06666be6cff0c5 (diff)
2006-02-18 Jeff Muizelaar <jeff@infidigm.net>
* poppler/CairoOutputDev.cc: * poppler/CairoOutputDev.h: * poppler/GfxState.cc: * poppler/GfxState.h: Add support for drawSoftMaskedImage to CairoOutputDev. Ugly but works.
Diffstat (limited to 'poppler')
-rw-r--r--poppler/CairoOutputDev.cc101
-rw-r--r--poppler/CairoOutputDev.h6
-rw-r--r--poppler/GfxState.cc50
-rw-r--r--poppler/GfxState.h2
4 files changed, 159 insertions, 0 deletions
diff --git a/poppler/CairoOutputDev.cc b/poppler/CairoOutputDev.cc
index c548ac09..fd00bfcc 100644
--- a/poppler/CairoOutputDev.cc
+++ b/poppler/CairoOutputDev.cc
@@ -552,6 +552,107 @@ void CairoOutputDev::drawImageMask(GfxState *state, Object *ref, Stream *str,
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();
+
+ int row_stride = (maskWidth + 3) & ~3;
+ unsigned char *maskBuffer;
+ maskBuffer = (unsigned char *)gmalloc (row_stride * maskHeight);
+ 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 * row_stride);
+ pix = maskImgStr->getLine();
+ maskColorMap->getGrayLine (pix, maskDest, maskWidth);
+ }
+
+ maskImage = cairo_image_surface_create_for_data (maskBuffer, CAIRO_FORMAT_A8,
+ maskWidth, maskHeight, row_stride);
+
+ 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,
diff --git a/poppler/CairoOutputDev.h b/poppler/CairoOutputDev.h
index 78f77eb2..bbf0ce44 100644
--- a/poppler/CairoOutputDev.h
+++ b/poppler/CairoOutputDev.h
@@ -117,6 +117,12 @@ public:
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);
diff --git a/poppler/GfxState.cc b/poppler/GfxState.cc
index 91f3ba12..62332922 100644
--- a/poppler/GfxState.cc
+++ b/poppler/GfxState.cc
@@ -205,6 +205,23 @@ void GfxColorSpace::getRGBLine(Guchar *in, unsigned int *out, int length) {
}
}
+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::getRGB(Guchar *x, GfxRGB *rgb) {
}
}
+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;
diff --git a/poppler/GfxState.h b/poppler/GfxState.h
index f7ec8dbb..2f59dca0 100644
--- a/poppler/GfxState.h
+++ b/poppler/GfxState.h
@@ -151,6 +151,7 @@ public:
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 @@ public:
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);