X-Git-Url: https://www.fi.muni.cz/~kas/git//home/kas/public_html/git/?a=blobdiff_plain;ds=sidebyside;f=pdf%2Fxpdf%2FGfxState.cc;h=a978b50b0be765b8b77cd8dfdb8977075c33dcc1;hb=8032fd96d450ac015c0153f1fa57e974d67b4993;hp=1668c246796924c0431b6879c3fca50540cd4fec;hpb=2a393c134fe3fe8eb85bf818cb7ad6ae4396322a;p=evince.git diff --git a/pdf/xpdf/GfxState.cc b/pdf/xpdf/GfxState.cc index 1668c246..a978b50b 100644 --- a/pdf/xpdf/GfxState.cc +++ b/pdf/xpdf/GfxState.cc @@ -6,11 +6,12 @@ // //======================================================================== -#ifdef __GNUC__ +#include + +#ifdef USE_GCC_PRAGMAS #pragma implementation #endif -#include #include #include #include // for memcpy() @@ -27,6 +28,24 @@ static inline double clip01(double x) { 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 //------------------------------------------------------------------------ @@ -98,6 +117,14 @@ void GfxColorSpace::getDefaultRanges(double *decodeLow, double *decodeRange, } } +int GfxColorSpace::getNumColorSpaceModes() { + return nGfxColorSpaceModes; +} + +char *GfxColorSpace::getColorSpaceModeName(int idx) { + return gfxColorSpaceModeNames[idx]; +} + //------------------------------------------------------------------------ // GfxDeviceGrayColorSpace //------------------------------------------------------------------------ @@ -410,6 +437,12 @@ void GfxDeviceCMYKColorSpace::getGray(GfxColor *color, double *gray) { 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]); @@ -788,9 +821,19 @@ GfxColorSpace *GfxIndexedColorSpace::parse(Array *arr) { 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); @@ -833,43 +876,37 @@ GfxColorSpace *GfxIndexedColorSpace::parse(Array *arr) { 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, @@ -1666,10 +1703,11 @@ GfxImageColorMap::GfxImageColorMap(int bitsA, Object *decode, 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) { @@ -1765,6 +1803,15 @@ void GfxImageColorMap::getCMYK(Guchar *x, GfxCMYK *cmyk) { } } +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 //------------------------------------------------------------------------