summaryrefslogtreecommitdiff
path: root/poppler
diff options
context:
space:
mode:
authorKristian Høgsberg <krh@redhat.com>2005-05-26 12:52:38 +0000
committerKristian Høgsberg <krh@redhat.com>2005-05-26 12:52:38 +0000
commit89a633edd860e3c6ded1e468edf6f28cfcb43d0e (patch)
treefba957d9df55e9df2de32635c552069d610adc21 /poppler
parent4d8224819da7a85e4d99f96c9bbb047ece58130a (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.cc66
-rw-r--r--poppler/GfxState.cc160
-rw-r--r--poppler/GfxState.h14
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