Commit 89a633ed authored by Kristian Høgsberg's avatar Kristian Høgsberg

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.
parent 4d822481
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.
Mon May 23 00:22:41 2005 Jonathan Blandford <jrb@redhat.com>
* glib/poppler-document.h: Add a permissions flag to the glib
......
......@@ -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);
......
......@@ -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;
......
......@@ -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
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment