//
//========================================================================
-#ifdef __GNUC__
+#include <aconf.h>
+
+#ifdef USE_GCC_PRAGMAS
#pragma implementation
#endif
-#include <aconf.h>
#include <stddef.h>
#include <math.h>
#include <string.h> // for memcpy()
return (x < 0) ? 0 : ((x > 1) ? 1 : x);
}
+//------------------------------------------------------------------------
+
+static char *gfxColorSpaceModeNames[] = {
+ "DeviceGray",
+ "CalGray",
+ "DeviceRGB",
+ "CalRGB",
+ "DeviceCMYK",
+ "Lab",
+ "ICCBased",
+ "Indexed",
+ "Separation",
+ "DeviceN",
+ "Pattern"
+};
+
+#define nGfxColorSpaceModes ((sizeof(gfxColorSpaceModeNames) / sizeof(char *)))
+
//------------------------------------------------------------------------
// GfxColorSpace
//------------------------------------------------------------------------
}
}
+int GfxColorSpace::getNumColorSpaceModes() {
+ return nGfxColorSpaceModes;
+}
+
+char *GfxColorSpace::getColorSpaceModeName(int idx) {
+ return gfxColorSpaceModeNames[idx];
+}
+
//------------------------------------------------------------------------
// GfxDeviceGrayColorSpace
//------------------------------------------------------------------------
void GfxDeviceCMYKColorSpace::getRGB(GfxColor *color, GfxRGB *rgb) {
double c, m, y, aw, ac, am, ay, ar, ag, ab;
+ /* FIXME ask Derek */
+ if (color->c[0] == 0.0 && color->c[1] == 0 && color->c[2] == 0) {
+ rgb->r = rgb->g = rgb->b = 1 - color->c[3];
+ return;
+ }
+
c = clip01(color->c[0] + color->c[3]);
m = clip01(color->c[1] + color->c[3]);
y = clip01(color->c[2] + color->c[3]);
obj1.free();
if (!arr->get(2, &obj1)->isInt()) {
error(-1, "Bad Indexed color space (hival)");
+ delete baseA;
goto err2;
}
indexHighA = obj1.getInt();
+ if (indexHighA < 0 || indexHighA > 255) {
+ // the PDF spec requires indexHigh to be in [0,255] -- allowing
+ // values larger than 255 creates a security hole: if nComps *
+ // indexHigh is greater than 2^31, the loop below may overwrite
+ // past the end of the array
+ error(-1, "Bad Indexed color space (invalid indexHigh value)");
+ delete baseA;
+ goto err2;
+ }
obj1.free();
cs = new GfxIndexedColorSpace(baseA, indexHighA);
arr->get(3, &obj1);
return NULL;
}
-void GfxIndexedColorSpace::getGray(GfxColor *color, double *gray) {
+GfxColor *GfxIndexedColorSpace::mapColorToBase(GfxColor *color,
+ GfxColor *baseColor) {
Guchar *p;
- GfxColor color2;
+ double low[gfxColorMaxComps], range[gfxColorMaxComps];
int n, i;
n = base->getNComps();
+ base->getDefaultRanges(low, range, indexHigh);
p = &lookup[(int)(color->c[0] + 0.5) * n];
for (i = 0; i < n; ++i) {
- color2.c[i] = p[i] / 255.0;
+ baseColor->c[i] = low[i] + (p[i] / 255.0) * range[i];
}
- base->getGray(&color2, gray);
+ return baseColor;
+}
+
+void GfxIndexedColorSpace::getGray(GfxColor *color, double *gray) {
+ GfxColor color2;
+
+ base->getGray(mapColorToBase(color, &color2), gray);
}
void GfxIndexedColorSpace::getRGB(GfxColor *color, GfxRGB *rgb) {
- Guchar *p;
GfxColor color2;
- int n, i;
- n = base->getNComps();
- p = &lookup[(int)(color->c[0] + 0.5) * n];
- for (i = 0; i < n; ++i) {
- color2.c[i] = p[i] / 255.0;
- }
- base->getRGB(&color2, rgb);
+ base->getRGB(mapColorToBase(color, &color2), rgb);
}
void GfxIndexedColorSpace::getCMYK(GfxColor *color, GfxCMYK *cmyk) {
- Guchar *p;
GfxColor color2;
- int n, i;
- n = base->getNComps();
- p = &lookup[(int)(color->c[0] + 0.5) * n];
- for (i = 0; i < n; ++i) {
- color2.c[i] = p[i] / 255.0;
- }
- base->getCMYK(&color2, cmyk);
+ base->getCMYK(mapColorToBase(color, &color2), cmyk);
}
void GfxIndexedColorSpace::getDefaultRanges(double *decodeLow,
nComps2 = colorSpace2->getNComps();
lookup = (double *)gmalloc((indexHigh + 1) * nComps2 * sizeof(double));
lookup2 = indexedCS->getLookup();
+ colorSpace2->getDefaultRanges(x, y, indexHigh);
for (i = 0; i <= indexHigh; ++i) {
- j = (int)(decodeLow[0] +(i * decodeRange[0]) / maxPixel + 0.5);
+ j = (int)(decodeLow[0] + (i * decodeRange[0]) / maxPixel + 0.5);
for (k = 0; k < nComps2; ++k) {
- lookup[i*nComps2 + k] = lookup2[i*nComps2 + k] / 255.0;
+ lookup[j*nComps2 + k] = x[k] + (lookup2[i*nComps2 + k] / 255.0) * y[k];
}
}
} else if (colorSpace->getMode() == csSeparation) {
}
}
+void GfxImageColorMap::getColor(Guchar *x, GfxColor *color) {
+ int maxPixel, i;
+
+ maxPixel = (1 << bits) - 1;
+ for (i = 0; i < nComps; ++i) {
+ color->c[i] = decodeLow[i] + (x[i] * decodeRange[i]) / maxPixel;
+ }
+}
+
//------------------------------------------------------------------------
// GfxSubpath and GfxPath
//------------------------------------------------------------------------