diff options
author | Kristian Høgsberg <krh@redhat.com> | 2005-05-26 12:52:38 +0000 |
---|---|---|
committer | Kristian Høgsberg <krh@redhat.com> | 2005-05-26 12:52:38 +0000 |
commit | 89a633edd860e3c6ded1e468edf6f28cfcb43d0e (patch) | |
tree | fba957d9df55e9df2de32635c552069d610adc21 /poppler | |
parent | 4d8224819da7a85e4d99f96c9bbb047ece58130a (diff) |
2005-05-26 Kristian Høgsberg <krh@redhat.com>
* poppler/GfxState.cc:
* poppler/GfxState.h: Add GfxColorSpace::getRGBLine here and
implement in subclasses.
* poppler/CairoOutputDev.cc (drawImage): Use getRGBLine here.
Diffstat (limited to 'poppler')
-rw-r--r-- | poppler/CairoOutputDev.cc | 66 | ||||
-rw-r--r-- | poppler/GfxState.cc | 160 | ||||
-rw-r--r-- | poppler/GfxState.h | 14 |
3 files changed, 204 insertions, 36 deletions
diff --git a/poppler/CairoOutputDev.cc b/poppler/CairoOutputDev.cc index 0ae18348..d9368fd9 100644 --- a/poppler/CairoOutputDev.cc +++ b/poppler/CairoOutputDev.cc @@ -311,7 +311,6 @@ void CairoOutputDev::clip(GfxState *state, GBool snapToGrid) { doPath (state, state->getPath(), snapToGrid); cairo_set_fill_rule (cairo, CAIRO_FILL_RULE_WINDING); cairo_clip (cairo); - cairo_new_path (cairo); /* Consume path */ LOG (printf ("clip\n")); } @@ -319,7 +318,6 @@ void CairoOutputDev::eoClip(GfxState *state) { doPath (state, state->getPath(), gFalse); cairo_set_fill_rule (cairo, CAIRO_FILL_RULE_EVEN_ODD); cairo_clip (cairo); - cairo_new_path (cairo); /* Consume path */ LOG (printf ("clip-eo\n")); } @@ -531,9 +529,10 @@ void CairoOutputDev::drawImageMask(GfxState *state, Object *ref, Stream *str, void CairoOutputDev::drawImage(GfxState *state, Object *ref, Stream *str, int width, int height, GfxImageColorMap *colorMap, - int *maskColors, GBool inlineImg) { + int *maskColors, GBool inlineImg) +{ unsigned char *buffer; - unsigned char *dest; + unsigned int *dest; cairo_surface_t *image; cairo_pattern_t *pattern; int x, y; @@ -545,12 +544,7 @@ void CairoOutputDev::drawImage(GfxState *state, Object *ref, Stream *str, cairo_matrix_t matrix; int is_identity_transform; - buffer = (unsigned char *)malloc (width * height * 4); - - if (buffer == NULL) { - error(-1, "Unable to allocate memory for image."); - return; - } + buffer = (unsigned char *)gmalloc (width * height * 4); /* TODO: Do we want to cache these? */ imgStr = new ImageStream(str, width, @@ -563,39 +557,41 @@ void CairoOutputDev::drawImage(GfxState *state, Object *ref, Stream *str, is_identity_transform = colorMap->getColorSpace()->getMode() == csDeviceRGB || colorMap->getColorSpace()->getMode() == csICCBased && ((GfxICCBasedColorSpace*)colorMap->getColorSpace())->getAlt()->getMode() == csDeviceRGB; - - for (y = 0; y < height; y++) { - dest = buffer + y * 4 * width; - pix = imgStr->getLine(); - for (x = 0; x < width; x++, pix += colorMap->getNumPixelComps()) { - if (maskColors) { - alpha = 0; + + if (maskColors) { + for (y = 0; y < height; y++) { + dest = (unsigned int *) (buffer + y * 4 * width); + pix = imgStr->getLine(); + colorMap->getRGBLine (pix, dest, width); + + for (x = 0; x < width; x++) { for (i = 0; i < colorMap->getNumPixelComps(); ++i) { - if (pix[i] < maskColors[2*i] || - pix[i] > maskColors[2*i+1]) { - alpha = 255; + + if (pix[i] < maskColors[2*i] * 255|| + pix[i] > maskColors[2*i+1] * 255) { + *dest = *dest | 0xff000000; break; } } - } else { - alpha = 255; - } - if (is_identity_transform) { - *dest++ = pix[2]; - *dest++ = pix[1]; - *dest++ = pix[0]; - } else { - colorMap->getRGB(pix, &rgb); - *dest++ = soutRound(255 * rgb.b); - *dest++ = soutRound(255 * rgb.g); - *dest++ = soutRound(255 * rgb.r); + pix += colorMap->getNumPixelComps(); + dest++; } - *dest++ = alpha; } + + image = cairo_image_surface_create_for_data (buffer, CAIRO_FORMAT_ARGB32, + width, height, width * 4); + } + else { + 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); } - image = cairo_image_surface_create_for_data (buffer, CAIRO_FORMAT_ARGB32, - width, height, width * 4); if (image == NULL) return; pattern = cairo_pattern_create_for_surface (image); diff --git a/poppler/GfxState.cc b/poppler/GfxState.cc index a159de6b..205f004e 100644 --- a/poppler/GfxState.cc +++ b/poppler/GfxState.cc @@ -125,6 +125,25 @@ char *GfxColorSpace::getColorSpaceModeName(int idx) { return gfxColorSpaceModeNames[idx]; } +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] / 255.0; + + getRGB (&color, &rgb); + out[i] = + ((int) (rgb.r * 255) << 16) | + ((int) (rgb.g * 255) << 8) | + ((int) (rgb.b * 255) << 0); + } +} + //------------------------------------------------------------------------ // GfxDeviceGrayColorSpace //------------------------------------------------------------------------ @@ -143,10 +162,22 @@ void GfxDeviceGrayColorSpace::getGray(GfxColor *color, double *gray) { *gray = clip01(color->c[0]); } +void GfxDeviceGrayColorSpace::getGrayLine(Guchar *in, Guchar *out, int length) { + memcpy (out, in, length); +} + void GfxDeviceGrayColorSpace::getRGB(GfxColor *color, GfxRGB *rgb) { rgb->r = rgb->g = rgb->b = clip01(color->c[0]); } +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); +} + void GfxDeviceGrayColorSpace::getCMYK(GfxColor *color, GfxCMYK *cmyk) { cmyk->c = cmyk->m = cmyk->y = 0; cmyk->k = clip01(1 - color->c[0]); @@ -228,10 +259,22 @@ void GfxCalGrayColorSpace::getGray(GfxColor *color, double *gray) { *gray = clip01(color->c[0]); } +void GfxCalGrayColorSpace::getGrayLine(Guchar *in, Guchar *out, int length) { + memcpy (out, in, length); +} + void GfxCalGrayColorSpace::getRGB(GfxColor *color, GfxRGB *rgb) { rgb->r = rgb->g = rgb->b = clip01(color->c[0]); } +void GfxCalGrayColorSpace::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); +} + void GfxCalGrayColorSpace::getCMYK(GfxColor *color, GfxCMYK *cmyk) { cmyk->c = cmyk->m = cmyk->y = 0; cmyk->k = clip01(1 - color->c[0]); @@ -257,12 +300,32 @@ void GfxDeviceRGBColorSpace::getGray(GfxColor *color, double *gray) { 0.114 * color->c[2]); } +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 + 0] * 38469 + + in[i * 3 + 0] * 7472) / 65536; + } +} + 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]); } +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); +} + void GfxDeviceRGBColorSpace::getCMYK(GfxColor *color, GfxCMYK *cmyk) { double c, m, y, k; @@ -388,12 +451,32 @@ void GfxCalRGBColorSpace::getGray(GfxColor *color, double *gray) { 0.114 * color->c[2]); } +void GfxCalRGBColorSpace::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 + 0] * 38469 + + in[i * 3 + 0] * 7472) / 65536; + } +} + void GfxCalRGBColorSpace::getRGB(GfxColor *color, GfxRGB *rgb) { rgb->r = clip01(color->c[0]); rgb->g = clip01(color->c[1]); rgb->b = clip01(color->c[2]); } +void GfxCalRGBColorSpace::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); +} + void GfxCalRGBColorSpace::getCMYK(GfxColor *color, GfxCMYK *cmyk) { double c, m, y, k; @@ -764,6 +847,11 @@ void GfxICCBasedColorSpace::getRGB(GfxColor *color, GfxRGB *rgb) { alt->getRGB(color, rgb); } +void GfxICCBasedColorSpace::getRGBLine(Guchar *in, unsigned int *out, + int length) { + alt->getRGBLine(in, out, length); +} + void GfxICCBasedColorSpace::getCMYK(GfxColor *color, GfxCMYK *cmyk) { alt->getCMYK(color, cmyk); } @@ -914,6 +1002,22 @@ void GfxIndexedColorSpace::getRGB(GfxColor *color, GfxRGB *rgb) { base->getRGB(mapColorToBase(color, &color2), rgb); } +void GfxIndexedColorSpace::getRGBLine(Guchar *in, unsigned int *out, int length) { + GfxColor color2; + Guchar *line; + int i, j, n; + + n = base->getNComps(); + line = (Guchar *) gmalloc (length * n); + for (i = 0; i < length; i++) + for (j = 0; j < n; j++) + line[i * n + j] = lookup[in[i] * n + j]; + + base->getRGBLine(line, out, length); + + gfree (line); +} + void GfxIndexedColorSpace::getCMYK(GfxColor *color, GfxCMYK *cmyk) { GfxColor color2; @@ -2049,6 +2153,7 @@ GfxImageColorMap::GfxImageColorMap(int bitsA, Object *decode, lookup = (double *)gmalloc((maxPixel + 1) * nComps2 * sizeof(double)); lookup2 = indexedCS->getLookup(); colorSpace2->getDefaultRanges(x, y, indexHigh); + byte_lookup = (Guchar *)gmalloc ((maxPixel + 1) * nComps2); for (i = 0; i <= maxPixel; ++i) { j = (int)(decodeLow[0] + (i * decodeRange[0]) / maxPixel + 0.5); if (j < 0) { @@ -2057,28 +2162,47 @@ GfxImageColorMap::GfxImageColorMap(int bitsA, Object *decode, j = indexHigh; } for (k = 0; k < nComps2; ++k) { - lookup[i*nComps2 + k] = x[k] + (lookup2[j*nComps2 + k] / 255.0) * y[k]; + double mapped; + + mapped = x[k] + (lookup2[j*nComps2 + k] / 255.0) * y[k]; + lookup[i*nComps2 + k] = mapped; + byte_lookup[i*nComps2 + k] = (Guchar) (mapped * 255); } } + } else if (colorSpace->getMode() == csSeparation) { sepCS = (GfxSeparationColorSpace *)colorSpace; colorSpace2 = sepCS->getAlt(); nComps2 = colorSpace2->getNComps(); lookup = (double *)gmalloc((maxPixel + 1) * nComps2 * sizeof(double)); + byte_lookup = (Guchar *)gmalloc ((maxPixel + 1) * nComps2); sepFunc = sepCS->getFunc(); for (i = 0; i <= maxPixel; ++i) { x[0] = decodeLow[0] + (i * decodeRange[0]) / maxPixel; sepFunc->transform(x, y); for (k = 0; k < nComps2; ++k) { lookup[i*nComps2 + k] = y[k]; + byte_lookup[i*nComps2 + k] = (Guchar) (y[k] * 255); } } } else { lookup = (double *)gmalloc((maxPixel + 1) * nComps * sizeof(double)); + byte_lookup = (Guchar *)gmalloc ((maxPixel + 1) * nComps); + for (i = 0; i <= maxPixel; ++i) { for (k = 0; k < nComps; ++k) { + int byte; + lookup[i*nComps + k] = decodeLow[k] + (i * decodeRange[k]) / maxPixel; + + byte = (int) (lookup[i*nComps + k] * 255 + 0.5); + if (byte < 0) + byte = 0; + else if (byte > 255) + byte = 255; + byte_lookup[i * nComps + k] = byte; + } } } @@ -2122,6 +2246,7 @@ GfxImageColorMap::GfxImageColorMap(GfxImageColorMap *colorMap) { GfxImageColorMap::~GfxImageColorMap() { delete colorSpace; gfree(lookup); + gfree(byte_lookup); } void GfxImageColorMap::getGray(Guchar *x, double *gray) { @@ -2162,6 +2287,39 @@ void GfxImageColorMap::getRGB(Guchar *x, GfxRGB *rgb) { } } +void GfxImageColorMap::getRGBLine(Guchar *in, unsigned int *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->getRGBLine(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->getRGBLine(in, out, length); + break; + } + +} + void GfxImageColorMap::getCMYK(Guchar *x, GfxCMYK *cmyk) { GfxColor color; double *p; diff --git a/poppler/GfxState.h b/poppler/GfxState.h index 2e7b4205..43c34963 100644 --- a/poppler/GfxState.h +++ b/poppler/GfxState.h @@ -83,6 +83,7 @@ public: virtual void getGray(GfxColor *color, double *gray) = 0; 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); // Return the number of color components. virtual int getNComps() = 0; @@ -116,6 +117,8 @@ public: virtual void getGray(GfxColor *color, double *gray); virtual void getRGB(GfxColor *color, GfxRGB *rgb); virtual void getCMYK(GfxColor *color, GfxCMYK *cmyk); + virtual void getGrayLine(Guchar *in, Guchar *out, int length); + virtual void getRGBLine(Guchar *in, unsigned int *out, int length); virtual int getNComps() { return 1; } @@ -140,6 +143,8 @@ public: virtual void getGray(GfxColor *color, double *gray); virtual void getRGB(GfxColor *color, GfxRGB *rgb); virtual void getCMYK(GfxColor *color, GfxCMYK *cmyk); + virtual void getGrayLine(Guchar *in, Guchar *out, int length); + virtual void getRGBLine(Guchar *in, unsigned int *out, int length); virtual int getNComps() { return 1; } @@ -174,6 +179,8 @@ public: virtual void getGray(GfxColor *color, double *gray); virtual void getRGB(GfxColor *color, GfxRGB *rgb); virtual void getCMYK(GfxColor *color, GfxCMYK *cmyk); + virtual void getGrayLine(Guchar *in, Guchar *out, int length); + virtual void getRGBLine(Guchar *in, unsigned int *out, int length); virtual int getNComps() { return 3; } @@ -198,6 +205,8 @@ public: virtual void getGray(GfxColor *color, double *gray); virtual void getRGB(GfxColor *color, GfxRGB *rgb); virtual void getCMYK(GfxColor *color, GfxCMYK *cmyk); + virtual void getGrayLine(Guchar *in, Guchar *out, int length); + virtual void getRGBLine(Guchar *in, unsigned int *out, int length); virtual int getNComps() { return 3; } @@ -306,6 +315,7 @@ public: virtual void getRGB(GfxColor *color, GfxRGB *rgb); virtual void getCMYK(GfxColor *color, GfxCMYK *cmyk); + virtual void getRGBLine(Guchar *in, unsigned int *out, int length); virtual int getNComps() { return nComps; } virtual void getDefaultRanges(double *decodeLow, double *decodeRange, @@ -341,6 +351,7 @@ public: virtual void getGray(GfxColor *color, double *gray); virtual void getRGB(GfxColor *color, GfxRGB *rgb); virtual void getCMYK(GfxColor *color, GfxCMYK *cmyk); + virtual void getRGBLine(Guchar *in, unsigned int *out, int length); virtual int getNComps() { return 1; } @@ -713,6 +724,7 @@ public: // Convert an image pixel to a color. void getGray(Guchar *x, double *gray); void getRGB(Guchar *x, GfxRGB *rgb); + void getRGBLine(Guchar *in, unsigned int *out, int length); void getCMYK(Guchar *x, GfxCMYK *cmyk); void getColor(Guchar *x, GfxColor *color); @@ -726,6 +738,8 @@ private: GfxColorSpace *colorSpace2; // secondary color space int nComps2; // number of components in colorSpace2 double *lookup; // lookup table + Guchar *byte_lookup; + Guchar *tmp_line; double // minimum values for each component decodeLow[gfxColorMaxComps]; double // max - min value for each component |