📄 gfxstate.cc
字号:
t2 = t1 + color->c[1] / 500; if (t2 >= (6.0 / 29.0)) { X = t2 * t2 * t2; } else { X = (108.0 / 841.0) * (t2 - (4.0 / 29.0)); } X *= whiteX; if (t1 >= (6.0 / 29.0)) { Y = t1 * t1 * t1; } else { Y = (108.0 / 841.0) * (t1 - (4.0 / 29.0)); } Y *= whiteY; t2 = t1 - color->c[2] / 200; if (t2 >= (6.0 / 29.0)) { Z = t2 * t2 * t2; } else { Z = (108.0 / 841.0) * (t2 - (4.0 / 29.0)); } Z *= whiteZ; // convert XYZ to RGB, including gamut mapping and gamma correction r = xyzrgb[0][0] * X + xyzrgb[0][1] * Y + xyzrgb[0][2] * Z; g = xyzrgb[1][0] * X + xyzrgb[1][1] * Y + xyzrgb[1][2] * Z; b = xyzrgb[2][0] * X + xyzrgb[2][1] * Y + xyzrgb[2][2] * Z; rgb->r = pow(clip01(r * kr), 0.5); rgb->g = pow(clip01(g * kg), 0.5); rgb->b = pow(clip01(b * kb), 0.5);}void GfxLabColorSpace::getCMYK(GfxColor *color, GfxCMYK *cmyk) { GfxRGB rgb; double c, m, y, k; getRGB(color, &rgb); c = clip01(1 - rgb.r); m = clip01(1 - rgb.g); y = clip01(1 - rgb.b); k = c; if (m < k) { k = m; } if (y < k) { k = y; } cmyk->c = c - k; cmyk->m = m - k; cmyk->y = y - k; cmyk->k = k;}void GfxLabColorSpace::getDefaultRanges(double *decodeLow, double *decodeRange, int maxImgPixel) { decodeLow[0] = 0; decodeRange[0] = 100; decodeLow[1] = aMin; decodeRange[1] = aMax - aMin; decodeLow[2] = bMin; decodeRange[2] = bMax - bMin;}//------------------------------------------------------------------------// GfxICCBasedColorSpace//------------------------------------------------------------------------GfxICCBasedColorSpace::GfxICCBasedColorSpace(int nCompsA, GfxColorSpace *altA, Ref *iccProfileStreamA) { nComps = nCompsA; alt = altA; iccProfileStream = *iccProfileStreamA; rangeMin[0] = rangeMin[1] = rangeMin[2] = rangeMin[3] = 0; rangeMax[0] = rangeMax[1] = rangeMax[2] = rangeMax[3] = 1;}GfxICCBasedColorSpace::~GfxICCBasedColorSpace() { delete alt;}GfxColorSpace *GfxICCBasedColorSpace::copy() { GfxICCBasedColorSpace *cs; int i; cs = new GfxICCBasedColorSpace(nComps, alt->copy(), &iccProfileStream); for (i = 0; i < 4; ++i) { cs->rangeMin[i] = rangeMin[i]; cs->rangeMax[i] = rangeMax[i]; } return cs;}GfxColorSpace *GfxICCBasedColorSpace::parse(Array *arr) { GfxICCBasedColorSpace *cs; Ref iccProfileStreamA; int nCompsA; GfxColorSpace *altA; Dict *dict; Object obj1, obj2, obj3; int i; arr->getNF(1, &obj1); if (obj1.isRef()) { iccProfileStreamA = obj1.getRef(); } else { iccProfileStreamA.num = 0; iccProfileStreamA.gen = 0; } obj1.free(); arr->get(1, &obj1); if (!obj1.isStream()) { error(-1, "Bad ICCBased color space (stream)"); obj1.free(); return NULL; } dict = obj1.streamGetDict(); if (!dict->lookup("N", &obj2)->isInt()) { error(-1, "Bad ICCBased color space (N)"); obj2.free(); obj1.free(); return NULL; } nCompsA = obj2.getInt(); obj2.free(); if (dict->lookup("Alternate", &obj2)->isNull() || !(altA = GfxColorSpace::parse(&obj2))) { switch (nCompsA) { case 1: altA = new GfxDeviceGrayColorSpace(); break; case 3: altA = new GfxDeviceRGBColorSpace(); break; case 4: altA = new GfxDeviceCMYKColorSpace(); break; default: error(-1, "Bad ICCBased color space - invalid N"); obj2.free(); obj1.free(); return NULL; } } obj2.free(); cs = new GfxICCBasedColorSpace(nCompsA, altA, &iccProfileStreamA); if (dict->lookup("Range", &obj2)->isArray() && obj2.arrayGetLength() == 2 * nCompsA) { for (i = 0; i < nCompsA; ++i) { obj2.arrayGet(2*i, &obj3); cs->rangeMin[i] = obj3.getNum(); obj3.free(); obj2.arrayGet(2*i+1, &obj3); cs->rangeMax[i] = obj3.getNum(); obj3.free(); } } obj2.free(); obj1.free(); return cs;}void GfxICCBasedColorSpace::getGray(GfxColor *color, double *gray) { alt->getGray(color, gray);}void GfxICCBasedColorSpace::getRGB(GfxColor *color, GfxRGB *rgb) { alt->getRGB(color, rgb);}void GfxICCBasedColorSpace::getCMYK(GfxColor *color, GfxCMYK *cmyk) { alt->getCMYK(color, cmyk);}void GfxICCBasedColorSpace::getDefaultRanges(double *decodeLow, double *decodeRange, int maxImgPixel) { int i; for (i = 0; i < nComps; ++i) { decodeLow[i] = rangeMin[i]; decodeRange[i] = rangeMax[i] - rangeMin[i]; }}//------------------------------------------------------------------------// GfxIndexedColorSpace//------------------------------------------------------------------------GfxIndexedColorSpace::GfxIndexedColorSpace(GfxColorSpace *baseA, int indexHighA) { base = baseA; indexHigh = indexHighA; lookup = (Guchar *)gmalloc((indexHigh + 1) * base->getNComps() * sizeof(Guchar));}GfxIndexedColorSpace::~GfxIndexedColorSpace() { delete base; gfree(lookup);}GfxColorSpace *GfxIndexedColorSpace::copy() { GfxIndexedColorSpace *cs; cs = new GfxIndexedColorSpace(base->copy(), indexHigh); memcpy(cs->lookup, lookup, (indexHigh + 1) * base->getNComps() * sizeof(Guchar)); return cs;}GfxColorSpace *GfxIndexedColorSpace::parse(Array *arr) { GfxIndexedColorSpace *cs; GfxColorSpace *baseA; int indexHighA; Object obj1; int x; char *s; int n, i, j; if (arr->getLength() != 4) { error(-1, "Bad Indexed color space"); goto err1; } arr->get(1, &obj1); if (!(baseA = GfxColorSpace::parse(&obj1))) { error(-1, "Bad Indexed color space (base color space)"); goto err2; } obj1.free(); if (!arr->get(2, &obj1)->isInt()) { error(-1, "Bad Indexed color space (hival)"); goto err2; } indexHighA = obj1.getInt(); obj1.free(); cs = new GfxIndexedColorSpace(baseA, indexHighA); arr->get(3, &obj1); n = baseA->getNComps(); if (obj1.isStream()) { obj1.streamReset(); for (i = 0; i <= indexHighA; ++i) { for (j = 0; j < n; ++j) { if ((x = obj1.streamGetChar()) == EOF) { error(-1, "Bad Indexed color space (lookup table stream too short)"); goto err3; } cs->lookup[i*n + j] = (Guchar)x; } } obj1.streamClose(); } else if (obj1.isString()) { if (obj1.getString()->getLength() < (indexHighA + 1) * n) { error(-1, "Bad Indexed color space (lookup table string too short)"); goto err3; } s = obj1.getString()->getCString(); for (i = 0; i <= indexHighA; ++i) { for (j = 0; j < n; ++j) { cs->lookup[i*n + j] = (Guchar)*s++; } } } else { error(-1, "Bad Indexed color space (lookup table)"); goto err3; } obj1.free(); return cs; err3: delete cs; err2: obj1.free(); err1: return NULL;}GfxColor *GfxIndexedColorSpace::mapColorToBase(GfxColor *color, GfxColor *baseColor) { Guchar *p; 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) { baseColor->c[i] = low[i] + (p[i] / 255.0) * range[i]; } return baseColor;}void GfxIndexedColorSpace::getGray(GfxColor *color, double *gray) { GfxColor color2; base->getGray(mapColorToBase(color, &color2), gray);}void GfxIndexedColorSpace::getRGB(GfxColor *color, GfxRGB *rgb) { GfxColor color2; base->getRGB(mapColorToBase(color, &color2), rgb);}void GfxIndexedColorSpace::getCMYK(GfxColor *color, GfxCMYK *cmyk) { GfxColor color2; base->getCMYK(mapColorToBase(color, &color2), cmyk);}void GfxIndexedColorSpace::getDefaultRanges(double *decodeLow, double *decodeRange, int maxImgPixel) { decodeLow[0] = 0; decodeRange[0] = maxImgPixel;}//------------------------------------------------------------------------// GfxSeparationColorSpace//------------------------------------------------------------------------GfxSeparationColorSpace::GfxSeparationColorSpace(GString *nameA, GfxColorSpace *altA, Function *funcA) { name = nameA; alt = altA; func = funcA;}GfxSeparationColorSpace::~GfxSeparationColorSpace() { delete name; delete alt; delete func;}GfxColorSpace *GfxSeparationColorSpace::copy() { return new GfxSeparationColorSpace(name->copy(), alt->copy(), func->copy());}//~ handle the 'All' and 'None' colorantsGfxColorSpace *GfxSeparationColorSpace::parse(Array *arr) { GfxSeparationColorSpace *cs; GString *nameA; GfxColorSpace *altA; Function *funcA; Object obj1; if (arr->getLength() != 4) { error(-1, "Bad Separation color space"); goto err1; } if (!arr->get(1, &obj1)->isName()) { error(-1, "Bad Separation color space (name)"); goto err2; } nameA = new GString(obj1.getName()); obj1.free(); arr->get(2, &obj1); if (!(altA = GfxColorSpace::parse(&obj1))) { error(-1, "Bad Separation color space (alternate color space)"); goto err3; } obj1.free(); arr->get(3, &obj1); if (!(funcA = Function::parse(&obj1))) { goto err4; } obj1.free(); cs = new GfxSeparationColorSpace(nameA, altA, funcA); return cs; err4: delete altA; err3: delete nameA; err2: obj1.free(); err1: return NULL;}void GfxSeparationColorSpace::getGray(GfxColor *color, double *gray) { GfxColor color2; func->transform(color->c, color2.c); alt->getGray(&color2, gray);}void GfxSeparationColorSpace::getRGB(GfxColor *color, GfxRGB *rgb) { GfxColor color2; func->transform(color->c, color2.c); alt->getRGB(&color2, rgb);}void GfxSeparationColorSpace::getCMYK(GfxColor *color, GfxCMYK *cmyk) { GfxColor color2; func->transform(color->c, color2.c); alt->getCMYK(&color2, cmyk);}//------------------------------------------------------------------------// GfxDeviceNColorSpace//------------------------------------------------------------------------GfxDeviceNColorSpace::GfxDeviceNColorSpace(int nCompsA, GfxColorSpace *altA, Function *funcA) { nComps = nCompsA; alt = altA; func = funcA;}GfxDeviceNColorSpace::~GfxDeviceNColorSpace() { int i; for (i = 0; i < nComps; ++i) { delete names[i]; } delete alt; delete func;}GfxColorSpace *GfxDeviceNColorSpace::copy() { GfxDeviceNColorSpace *cs; int i; cs = new GfxDeviceNColorSpace(nComps, alt->copy(), func->copy()); for (i = 0; i < nComps; ++i) { cs->names[i] = names[i]->copy(); } return cs;}//~ handle the 'None' colorantGfxColorSpace *GfxDeviceNColorSpace::parse(Array *arr) { GfxDeviceNColorSpace *cs; int nCompsA; GString *namesA[gfxColorMaxComps]; GfxColorSpace *altA; Function *funcA; Object obj1, obj2; int i; if (arr->getLength() != 4 && arr->getLength() != 5) { error(-1, "Bad DeviceN color space"); goto err1; } if (!arr->get(1, &obj1)->isArray()) { error(-1, "Bad DeviceN color space (names)"); goto err2; } nCompsA = obj1.arrayGetLength(); for (i = 0; i < nCompsA; ++i) { if (!obj1.arrayGet(i, &obj2)->isName()) { error(-1, "Bad DeviceN color space (names)"); obj2.free(); goto err2; } namesA[i] = new GString(obj2.getName()); obj2.free(); } obj1.free(); arr->get(2, &obj1); if (!(altA = GfxColorSpace::parse(&obj1))) { error(-1, "Bad DeviceN color space (alternate color space)"); goto err3; } obj1.free(); arr->get(3, &obj1); if (!(funcA = Function::parse(&obj1))) { goto err4; } obj1.free(); cs = new GfxDeviceNColorSpace(nCompsA, altA, funcA); for (i = 0; i < nCompsA; ++i) { cs->names[i] = namesA[i]; } return cs; err4: delete altA; err3: for (i = 0; i < nCompsA; ++i) { delete namesA[i]; } err2: obj1.free(); err1: return NULL;}void GfxDeviceNColorSpace::getGray(GfxColor *color, double *gray) { GfxColor color2; func->transform(color->c, color2.c); alt->getGray(&color2, gray);}void GfxDeviceNColorSpace::getRGB(GfxColor *color, GfxRGB *rgb) { GfxColor color2; func->transform(color->c, color2.c); alt->getRGB(&color2, rgb);}void GfxDeviceNColorSpace::getCMYK(GfxColor *color, GfxCMYK *cmyk) { GfxColor color2; func->transform(color->c, color2.c); alt->getCMYK(&color2, cmyk);}//------------------------------------------------------------------------// GfxPatternColorSpace//------------------------------------------------------------------------GfxPatternColorSpace::GfxPatternColorSpace(GfxColorSpace *underA) { under = underA;}GfxPatternColorSpace::~GfxPatternColorSpace() { if (under) { delete under; }}GfxColorSpace *GfxPatternColorSpace::copy() { return new GfxPatternColorSpace(under ? under->copy() : (GfxColorSpace *)NULL);}GfxColorSpace *GfxPatternColorSpace::parse(Array *arr) { GfxPatternColorSpace *cs; GfxColorSpace *underA; Object obj1; if (arr->getLength() != 1 && arr->getLength() != 2) { error(-1, "Bad Pattern color space"); return NULL; } underA = NULL; if (arr->getLength() == 2) { arr->get(1, &obj1); if (!(underA = GfxColorSpace::parse(&obj1))) { error(-1, "Bad Pattern color space (underlying color space)"); obj1.free(); return NULL; } obj1.free(); } cs = new GfxPatternColorSpace(underA); return cs;}void GfxPatternColorSpace::getGray(GfxColor *color, double *gray) { *gray = 0;}void GfxPatternColorSpace::getRGB(GfxColor *color, GfxRGB *rgb) { rgb->r = rgb->g = rgb->b = 0;}void GfxPatternColorSpace::getCMYK(GfxColor *color, GfxCMYK *cmyk) { cmyk->c = cmyk->m = cmyk->y = 0; cmyk->k = 1;}//------------------------------------------------------------------------// Pattern//------------------------------------------------------------------------GfxPattern::GfxPattern(int typeA) { type = typeA;}GfxPattern::~GfxPattern() {}GfxPattern *GfxPattern::parse(Object *obj) { GfxPattern *pattern; Dict *dict; Object obj1; pattern = NULL; if (obj->isStream()) { dict = obj->streamGetDict(); dict->lookup("PatternType", &obj1); if (obj1.isInt() && obj1.getInt() == 1) { pattern = new GfxTilingPattern(dict, obj);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -