diff options
Diffstat (limited to 'Build/source/texk/dvipdfm-x/src/pdfcolor.c')
-rw-r--r-- | Build/source/texk/dvipdfm-x/src/pdfcolor.c | 1580 |
1 files changed, 0 insertions, 1580 deletions
diff --git a/Build/source/texk/dvipdfm-x/src/pdfcolor.c b/Build/source/texk/dvipdfm-x/src/pdfcolor.c deleted file mode 100644 index 988f4ec6e4a..00000000000 --- a/Build/source/texk/dvipdfm-x/src/pdfcolor.c +++ /dev/null @@ -1,1580 +0,0 @@ -/* - - This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. - - Copyright (C) 2002-2012 by Jin-Hwan Cho and Shunsaku Hirata, - the dvipdfmx project team. - - Copyright (C) 1998, 1999 by Mark A. Wicks <mwicks@kettering.edu> - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. -*/ - -/* No page independence here... - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include "system.h" -#include "mem.h" -#include "error.h" - -#include "dpxfile.h" - -#include "pdfdoc.h" -#include "pdfdraw.h" - -#include "pdfcolor.h" - - -static int verbose = 0; -void -pdf_color_set_verbose (void) -{ - verbose++; -} - -#ifndef XETEX -/* This function returns PDF_COLORSPACE_TYPE_GRAY, - * PDF_COLORSPACE_TYPE_RGB or PDF_COLORSPACE_TYPE_CMYK. - */ -int -pdf_color_type (const pdf_color *color) -{ - ASSERT(color); - - return -color->num_components; -} -#endif - -int -pdf_color_rgbcolor (pdf_color *color, double r, double g, double b) -{ - ASSERT(color); - - if (r < 0.0 || r > 1.0) { - WARN("Invalid color value specified: red=%g", r); - return -1; - } - if (g < 0.0 || g > 1.0) { - WARN("Invalid color value specified: green=%g", g); - return -1; - } - if (b < 0.0 || b > 1.0) { - WARN("Invalid color value specified: blue=%g", b); - return -1; - } - color->values[0] = r; - color->values[1] = g; - color->values[2] = b; - - color->num_components = 3; - - return 0; -} - -int -pdf_color_cmykcolor (pdf_color *color, - double c, double m, double y, double k) -{ - ASSERT(color); - - if (c < 0.0 || c > 1.0) { - WARN("Invalid color value specified: cyan=%g", c); - return -1; - } - if (m < 0.0 || m > 1.0) { - WARN("Invalid color value specified: magenta=%g", m); - return -1; - } - if (y < 0.0 || y > 1.0) { - WARN("Invalid color value specified: yellow=%g", y); - return -1; - } - if (k < 0.0 || k > 1.0) { - WARN("Invalid color value specified: black=%g", k); - return -1; - } - - color->values[0] = c; - color->values[1] = m; - color->values[2] = y; - color->values[3] = k; - - color->num_components = 4; - - return 0; -} - -int -pdf_color_graycolor (pdf_color *color, double g) -{ - ASSERT(color); - - if (g < 0.0 || g > 1.0) { - WARN("Invalid color value specified: gray=%g", g); - return -1; - } - - color->values[0] = g; - - color->num_components = 1; - - return 0; -} - - -void -pdf_color_copycolor (pdf_color *color1, const pdf_color *color2) -{ - ASSERT(color1 && color2); - - memcpy(color1, color2, sizeof(pdf_color)); -} - -#ifndef XETEX -/* Brighten up a color. f == 0 means no change, f == 1 means white. */ -void -pdf_color_brighten_color (pdf_color *dst, const pdf_color *src, double f) -{ - ASSERT(dst && src); - - if (f == 1.0) { - pdf_color_white(dst); - } else { - double f0, f1; - int n; - - n = dst->num_components = src->num_components; - f1 = n == 4 ? 0.0 : f; /* n == 4 is CMYK, others are RGB and Gray */ - f0 = 1.0-f; - - while (n--) - dst->values[n] = f0 * src->values[n] + f1; - } -} -#endif - -int -pdf_color_is_white (const pdf_color *color) -{ - int n; - double f; - - ASSERT(color); - - n = color->num_components; - switch (n) { - case 1: /* Gray */ - case 3: /* RGB */ - f = 1.0; - break; - case 4: /* CMYK */ - f = 0.0; - break; - default: - return 0; - } - - while (n--) - if (color->values[n] != f) - return 0; - - return 1; -} - -#ifndef XETEX -int -pdf_color_to_string (const pdf_color *color, char *buffer) -{ - int i, len = 0; - - for (i = 0; i < color->num_components; i++) { - len += sprintf(buffer+len, " %g", ROUND(color->values[i], 0.001)); - } - return len; -} -#endif - -pdf_color current_fill = { - 1, - {0.0, 0.0, 0.0, 0.0} -}; - -pdf_color current_stroke = { - 1, - {0.0, 0.0, 0.0, 0.0} -}; - -#ifndef XETEX -/* - * This routine is not a real color matching. - */ -int -pdf_color_compare (const pdf_color *color1, const pdf_color *color2) -{ - int n; - - n = color1->num_components; - switch (n) { - case 1: /* Gray */ - case 3: /* RGB */ - case 4: /* CMYK */ - break; - default: - return -1; - } - - if (n != color2->num_components) - return -1; - - while (n--) - if (color1->values[n] != color2->values[n]) - return -1; - - return 0; -} -#endif - -int -pdf_color_is_valid (const pdf_color *color) -{ - int n; - - n = color->num_components; - switch (n) { - case 1: /* Gray */ - case 3: /* RGB */ - case 4: /* CMYK */ - break; - default: - return 0; - } - - while (n--) - if (color->values[n] < 0.0 || color->values[n] > 1.0) { - WARN("Invalid color value: %g", color->values[n]); - return 0; - } - - return 1; -} - -/* Dvipdfm special */ -pdf_color default_color = { - 1, - {0.0, 0.0, 0.0, 0.0} -}; - -void -pdf_color_set_default (const pdf_color *color) -{ - pdf_color_copycolor(&default_color, color); -} - -#define DEV_COLOR_STACK_MAX 128 - -static struct { - int current; - pdf_color stroke[DEV_COLOR_STACK_MAX]; - pdf_color fill[DEV_COLOR_STACK_MAX]; -} color_stack; - -void -pdf_color_clear_stack (void) -{ - if (color_stack.current > 0) { - WARN("You've mistakenly made a global color change within nested colors."); - } - color_stack.current = 0; - pdf_color_black(color_stack.stroke); - pdf_color_black(color_stack.fill); - return; -} - -#ifndef XETEX -void -pdf_color_set (pdf_color *sc, pdf_color *fc) -{ - pdf_color_copycolor(&color_stack.stroke[color_stack.current], sc); - pdf_color_copycolor(&color_stack.fill[color_stack.current], fc); - pdf_dev_reset_color(0); -} -#endif - -void -pdf_color_push (pdf_color *sc, pdf_color *fc) -{ - if (color_stack.current >= DEV_COLOR_STACK_MAX-1) { - WARN("Color stack overflow. Just ignore."); - } else { - color_stack.current++; - pdf_color_set(sc, fc); - } - return; -} - -void -pdf_color_pop (void) -{ - if (color_stack.current <= 0) { - WARN("Color stack underflow. Just ignore."); - } else { - color_stack.current--; - pdf_dev_reset_color(0); - } - return; -} - -void -pdf_color_get_current (pdf_color **sc, pdf_color **fc) -{ - *sc = &color_stack.stroke[color_stack.current]; - *fc = &color_stack.fill[color_stack.current]; - return; -} - -#ifdef XETEX -/* BUG (20060330): color change does not effect on the next page. - * The problem is due to the part of grestore because it restores - * the color values in the state of gsave which are not correct - * if the color values are changed inside of a page. - */ -void -pdf_dev_preserve_color (void) -{ - if (color_stack.current > 0) { - current_stroke = color_stack.stroke[color_stack.current]; - current_fill = color_stack.fill[color_stack.current]; - } -} -#endif - -/***************************** COLOR SPACE *****************************/ - -static int pdf_colorspace_defineresource (const char *ident, - int subtype, - void *cdata, pdf_obj *resource); - -static int pdf_colorspace_findresource (const char *ident, - int subtype, const void *cdata); - -#if 0 -struct calgray_cdata -{ - double white_point[3]; /* required, second component must - * be equal to 1.0 - */ - double black_point[3]; /* optional, default: [0 0 0] */ - double gamma; /* optional, default: 1.0 */ -}; - -struct calrgb_cdata -{ - double white_point[3]; /* required, second component must - * be equal to 1.0 - */ - double black_point[3]; /* optional, default: [0 0 0] */ - double gamma[3]; /* optional, default: [1 1 1] */ - double matrix[9]; /* optional, default: identity - * [1 0 0 0 1 0 0 0 1] - */ -}; - -static void -release_calrgb (void *cdata) -{ - struct calrgb_cdata *calrgb; - - if (cdata) { - calrgb = (struct calrgb_cdata *) cdata; - RELEASE(calrgb); - } -} - -static int -compare_calrgb (const char *ident1, const void *cdata1, - const char *ident2, const void *cdata2) -{ - struct calrgb_cdata *calrgb1; - struct calrgb_cdata *calrgb2; - - if (ident1 && ident2 && - !strcmp(ident1, ident2)) { - return 0; - } -} - -static void -init_calrgb (struct calrgb_cdata *calrgb) -{ - ASSERT(calrgb); - - calrgb->white_point[0] = 1.0; - calrgb->white_point[1] = 1.0; - calrgb->white_point[2] = 1.0; - - calrgb->black_point[0] = 0.0; - calrgb->black_point[1] = 0.0; - calrgb->black_point[2] = 0.0; - - calrgb->gamma[0] = 1.0; - calrgb->gamma[1] = 1.0; - calrgb->gamma[2] = 1.0; - - calrgb->matrix[0] = 1.0; - calrgb->matrix[1] = 0.0; - calrgb->matrix[2] = 0.0; - - calrgb->matrix[3] = 0.0; - calrgb->matrix[4] = 1.0; - calrgb->matrix[5] = 0.0; - - calrgb->matrix[6] = 0.0; - calrgb->matrix[7] = 0.0; - calrgb->matrix[8] = 1.0; -} - -static int -valid_calrgb (struct calrgb_cdata *calrgb) -{ - if (calrgb->white_point[1] != 1.0 || - calrgb->white_point[0] <= 0.0 || - calrgb->white_point[2] <= 0.0) - return 0; - - if (calrgb->black_point[0] < 0.0 || - calrgb->black_point[1] < 0.0 || - calrgb->black_point[2] < 0.0) - return 0; - - if (calrgb->gamma[0] < 0.0 || - calrgb->gamma[1] < 0.0 || - calrgb->gamma[2] < 0.0) - return 0; - - /* matrix should be invertible? */ - - return 1; -} - -static pdf_obj * -pdf_color_make_calrgb_resource (struct calrgb_cdata *calrgb) -{ - pdf_obj *colorspace; - pdf_obj *calparams, *tmp_array; - - ASSERT(calrgb); - - if (!valid_calrgb(calrgb)) - return NULL; - - colorspace = pdf_new_array(); - calparams = pdf_new_dict(); - - tmp_array = pdf_new_array(); - pdf_add_array(tmp_array, pdf_new_number(ROUND(calrgb->white_point[0], 0.001))); - pdf_add_array(tmp_array, pdf_new_number(1.0)); - pdf_add_array(tmp_array, pdf_new_number(ROUND(calrgb->white_point[2], 0.001))); - pdf_add_dict(calparams, pdf_new_name("WhitePoint"), tmp_array); - - if (calrgb->black_point[0] != 0.0 || - calrgb->black_point[1] != 0.0 || - calrgb->black_point[2] != 0.0) { - tmp_array = pdf_new_array(); - pdf_add_array(tmp_array, pdf_new_number(ROUND(calrgb->black_point[0], 0.001))); - pdf_add_array(tmp_array, pdf_new_number(ROUND(calrgb->black_point[1], 0.001))); - pdf_add_array(tmp_array, pdf_new_number(ROUND(calrgb->black_point[2], 0.001))); - pdf_add_dict(calparams, pdf_new_name("BlackPoint"), tmp_array); - } - - if (calrgb->gamma[0] != 1.0 || - calrgb->gamma[1] != 1.0 || - calrgb->gamma[2] != 1.0) { - tmp_array = pdf_new_array(); - pdf_add_array(tmp_array, pdf_new_number(ROUND(calrgb->gamma[0], 0.001))); - pdf_add_array(tmp_array, pdf_new_number(ROUND(calrgb->gamma[1], 0.001))); - pdf_add_array(tmp_array, pdf_new_number(ROUND(calrgb->gamma[2], 0.001))); - pdf_add_dict(calparams, pdf_new_name("Gamma"), tmp_array); - } - - if (calrgb->matrix[0] != 1.0 || - calrgb->matrix[1] != 0.0 || - calrgb->matrix[2] != 0.0 || - calrgb->matrix[3] != 0.0 || - calrgb->matrix[4] != 1.0 || - calrgb->matrix[5] != 0.0 || - calrgb->matrix[6] != 0.0 || - calrgb->matrix[7] != 0.0 || - calrgb->matrix[8] != 1.0) { - tmp_array = pdf_new_array(); - pdf_add_array(tmp_array, pdf_new_number(ROUND(calrgb->matrix[0], 0.001))); - pdf_add_array(tmp_array, pdf_new_number(ROUND(calrgb->matrix[1], 0.001))); - pdf_add_array(tmp_array, pdf_new_number(ROUND(calrgb->matrix[2], 0.001))); - pdf_add_array(tmp_array, pdf_new_number(ROUND(calrgb->matrix[3], 0.001))); - pdf_add_array(tmp_array, pdf_new_number(ROUND(calrgb->matrix[4], 0.001))); - pdf_add_array(tmp_array, pdf_new_number(ROUND(calrgb->matrix[5], 0.001))); - pdf_add_array(tmp_array, pdf_new_number(ROUND(calrgb->matrix[6], 0.001))); - pdf_add_array(tmp_array, pdf_new_number(ROUND(calrgb->matrix[7], 0.001))); - pdf_add_array(tmp_array, pdf_new_number(ROUND(calrgb->matrix[8], 0.001))); - pdf_add_dict(calparams, pdf_new_name("Matrix"), tmp_array); - } - - pdf_add_array(colorspace, pdf_new_name("CalRGB")); - pdf_add_array(colorspace, calparams); - - return colorspace; -} -#endif - -static unsigned char nullbytes16[16] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 -}; - -static struct -{ - int major; - int minor; -} icc_versions[] = { - {0, 0}, /* PDF-1.0, we don't support them */ - {0, 0}, /* PDF-1.1, we don't support them */ - {0, 0}, /* PDF-1.2, we don't support them */ - {0x02, 0x10}, /* PDF-1.3 */ - {0x02, 0x20}, /* PDF-1.4 */ - {0x04, 0x00} /* PDF-1.5 */ -}; - -static int -iccp_version_supported (int major, int minor) -{ - int pdf_ver; - - pdf_ver = pdf_get_version(); - if (pdf_ver < 6) { - if (icc_versions[pdf_ver].major < major) - return 0; - else if (icc_versions[pdf_ver].major == major && - icc_versions[pdf_ver].minor < minor) - return 0; - else { - return 1; - } - } - - return 0; -} - -typedef unsigned long iccSig; -static iccSig -str2iccSig (const void *s) -{ - const char *p; - - p = (const char *) s; - - return (iccSig) ((p[0]<<24)|(p[1]<<16)|(p[2]<<8)|p[3]); -} - -typedef struct -{ - long X, Y, Z; /* s15Fixed16Numeber */ -} iccXYZNumber; - -typedef struct -{ - long size; - iccSig CMMType; - long version; - iccSig devClass; - iccSig colorSpace; - iccSig PCS; /* Profile Connection Space */ - char creationDate[12]; - iccSig acsp; - iccSig platform; - char flags[4]; - iccSig devMnfct; - iccSig devModel; - char devAttr[8]; - long intent; - iccXYZNumber illuminant; - iccSig creator; - unsigned char ID[16]; /* MD5 checksum with Rendering intent, - * Header attrs, Profile ID fields are - * set to zeros. - */ - /* 28 bytes reserved - must be set to zeros */ -} iccHeader; - -#define iccNullSig 0 -static void -iccp_init_iccHeader (iccHeader *icch) -{ - ASSERT(icch); - - icch->size = 0; - icch->CMMType = iccNullSig; - icch->version = 0xFFFFFF; - icch->devClass = iccNullSig; - icch->colorSpace = iccNullSig; - icch->PCS = iccNullSig; - memset(icch->creationDate, 0, 12); - icch->acsp = str2iccSig("ascp"); - icch->platform = iccNullSig; - memset(icch->flags, 0, 4); - icch->devMnfct = iccNullSig; - icch->devModel = iccNullSig; - memset(icch->devAttr, 0, 8); - icch->intent = 0; - icch->illuminant.X = 0; - icch->illuminant.Y = 0; - icch->illuminant.Z = 0; - icch->creator = iccNullSig; - memset(icch->ID, 0, 16); -} - -#define ICC_INTENT_TYPE(n) ((int) (((n) >> 16) & 0xff)) -#define ICC_INTENT_PERCEPTUAL 0 -#define ICC_INTENT_RELATIVE 1 -#define ICC_INTENT_SATURATION 2 -#define ICC_INTENT_ABSOLUTE 3 - -/* - * In ICC profile stream dicrionary, there is /Range whose values must - * "match the information in the profile". But where is those values in? - * - * How should I treat rendering intent? - */ -struct iccbased_cdata -{ - long sig; /* 'i' 'c' 'c' 'b' */ - - unsigned char checksum[16]; /* 16 bytes MD5 Checksum */ - int colorspace; /* input colorspace: - * RGB, Gray, CMYK, (Lab?) - */ - int alternate; /* alternate colorspace (id), unused */ -}; - -#define check_sig(d,p,q,r,s) ((d) && (d)->sig == ((p)<<24|(q)<<16|(r)<<8|(s))) - -static void -init_iccbased_cdata (struct iccbased_cdata *cdata) -{ - ASSERT(cdata); - - cdata->sig = ('i' << 24|'c' << 16|'c' << 8|'b'); - memset(cdata->checksum, 0, 16); - cdata->colorspace = PDF_COLORSPACE_TYPE_INVALID; - cdata->alternate = -1; - - return; -} - -static void -release_iccbased_cdata (struct iccbased_cdata *cdata) -{ - ASSERT(check_sig(cdata, 'i', 'c', 'c', 'b')); - - RELEASE(cdata); -} - -static int -get_num_components_iccbased (const struct iccbased_cdata *cdata) -{ - int num_components = 0; - - ASSERT(check_sig(cdata, 'i', 'c', 'c', 'b')); - - switch (cdata->colorspace) { - case PDF_COLORSPACE_TYPE_RGB: - num_components = 3; - break; - case PDF_COLORSPACE_TYPE_CMYK: - num_components = 4; - break; - case PDF_COLORSPACE_TYPE_GRAY: - num_components = 1; - break; - case PDF_COLORSPACE_TYPE_CIELAB: - num_components = 3; - break; - } - - return num_components; -} - -static int -compare_iccbased (const char *ident1, const struct iccbased_cdata *cdata1, - const char *ident2, const struct iccbased_cdata *cdata2) -{ - if (cdata1 && cdata2) { - - ASSERT(check_sig(cdata1, 'i', 'c', 'c', 'b')); - ASSERT(check_sig(cdata2, 'i', 'c', 'c', 'b')); - - if (memcmp(cdata1->checksum, nullbytes16, 16) && - memcmp(cdata2->checksum, nullbytes16, 16)) { - return memcmp(cdata1->checksum, cdata2->checksum, 16); - } - if (cdata1->colorspace != cdata2->colorspace) { - return (cdata1->colorspace - cdata2->colorspace); - } - - /* Continue if checksum unknown and colorspace is same. */ - } - - if (ident1 && ident2) - return strcmp(ident1, ident2); - - /* No way to compare */ - return -1; -} - -int -iccp_check_colorspace (int colortype, const void *profile, long proflen) -{ - iccSig colorspace; - const unsigned char *p; - - if (!profile || proflen < 128) - return -1; - - p = (const unsigned char *) profile; - - colorspace = str2iccSig(p + 16); - - switch (colortype) { - case PDF_COLORSPACE_TYPE_CALRGB: - case PDF_COLORSPACE_TYPE_RGB: - if (colorspace != str2iccSig("RGB ")) { - return -1; - } - break; - case PDF_COLORSPACE_TYPE_CALGRAY: - case PDF_COLORSPACE_TYPE_GRAY: - if (colorspace != str2iccSig("GRAY")) { - return -1; - } - break; - case PDF_COLORSPACE_TYPE_CMYK: - if (colorspace != str2iccSig("CMYK")) { - return -1; - } - break; - default: - return -1; - break; - } - - return 0; -} - -pdf_obj * -iccp_get_rendering_intent (const void *profile, long proflen) -{ - pdf_obj *ri = NULL; - const unsigned char *p; - long intent; - - if (!profile || proflen < 128) - return NULL; - - p = (const unsigned char *) profile; - - intent = (p[64] << 24)|(p[65] << 16)|(p[66] << 8)|p[67]; - switch (ICC_INTENT_TYPE(intent)) { - case ICC_INTENT_SATURATION: - ri = pdf_new_name("Saturation"); - break; - case ICC_INTENT_PERCEPTUAL: - ri = pdf_new_name("Perceptual"); - break; - case ICC_INTENT_ABSOLUTE: - ri = pdf_new_name("AbsoluteColorimetric"); - break; - case ICC_INTENT_RELATIVE: - ri = pdf_new_name("RelativeColorimetric"); - break; - default: - WARN("Invalid rendering intent type: %d", ICC_INTENT_TYPE(intent)); - ri = NULL; - } - - return ri; -} - -#define sget_signed_long(p) ((long) ((p)[0] << 24|(p)[1] << 16|(p)[2] << 8|(p)[3])) -#define sget_signed_short(p) ((short) ((p)[0] << 8|(p)[1])) -#define get_iccSig(p) ((iccSig) ((p)[0] << 24|(p)[1] << 16|(p)[2] << 8|(p)[3])) - -static int -iccp_unpack_header (iccHeader *icch, - const void *profile, long proflen, int check_size) -{ - const unsigned char *p, *endptr; - - if (check_size) { - if (!profile || proflen < 128 || - proflen % 4 != 0) { - WARN("Profile size: %ld", proflen); - return -1; - } - } - - p = (const unsigned char *) profile; - endptr = p + 128; - - icch->size = sget_signed_long(p); - if (check_size) { - if (icch->size != proflen) { - WARN("ICC Profile size: %ld(header) != %ld", icch->size, proflen); - return -1; - } - } - p += 4; - - icch->CMMType = str2iccSig(p); - p += 4; - icch->version = sget_signed_long(p); - p += 4; - icch->devClass = str2iccSig(p); - p += 4; - icch->colorSpace = str2iccSig(p); - p += 4; - icch->PCS = str2iccSig(p); - p += 4; - memcpy(icch->creationDate, p, 12); - p += 12; - icch->acsp = str2iccSig(p); /* acsp */ - if (icch->acsp != str2iccSig("acsp")) { - WARN("Invalid ICC profile: not \"acsp\" - %c%c%c%c ", - p[0], p[1], p[2], p[3]); - return -1; - } - p += 4; - icch->platform = str2iccSig(p); - p += 4; - memcpy(icch->flags, p, 4); - p += 4; - icch->devMnfct = str2iccSig(p); - p += 4; - icch->devModel = str2iccSig(p); - p += 4; - memcpy(icch->devAttr, p, 8); - p += 8; - icch->intent = (p[0] << 24)|(p[1] << 16)|(p[2] << 8)|p[3]; - p += 4; - icch->illuminant.X = sget_signed_long(p); - p += 4; - icch->illuminant.Y = sget_signed_long(p); - p += 4; - icch->illuminant.Z = sget_signed_long(p); - p += 4; - icch->creator = str2iccSig(p); - p += 4; - memcpy(icch->ID, p, 16); - p += 16; - - /* 28 bytes reserved - must be set to zeros */ - for (; p < endptr; p++) { - if (*p != '\0') { - WARN("Reserved pad not zero: %02x (at offset %ld in ICC profile header.)", - *p, 128 - ((long) (endptr - p))); - return -1; - } - } - - return 0; -} - -/* MD5 checksum with Rendering intent, - * Header attrs, Profile ID fields are - * set to zeros. - */ -#define ICC_HEAD_SECT1_START 0 -#define ICC_HEAD_SECT1_LENGTH 56 -/* 8 bytes devAttr, 4 bytes intent */ -#define ICC_HEAD_SECT2_START 68 -#define ICC_HEAD_SECT2_LENGTH 16 -/* 16 bytes ID (checksum) */ -#define ICC_HEAD_SECT3_START 100 -#define ICC_HEAD_SECT3_LENGTH 28 - -#include "dpxcrypt.h" -static void -iccp_get_checksum (unsigned char *checksum, const void *profile, long proflen) -{ - const unsigned char *p; - MD5_CONTEXT md5; - - p = (const unsigned char *) profile; - - MD5_init (&md5); - MD5_write(&md5, p + ICC_HEAD_SECT1_START, ICC_HEAD_SECT1_LENGTH); - MD5_write(&md5, nullbytes16, 12); - MD5_write(&md5, p + ICC_HEAD_SECT2_START, ICC_HEAD_SECT2_LENGTH); - MD5_write(&md5, nullbytes16, 16); - MD5_write(&md5, p + ICC_HEAD_SECT3_START, ICC_HEAD_SECT3_LENGTH); - - /* body */ - MD5_write(&md5, p + 128, proflen - 128); - - MD5_final(checksum, &md5); -} - -static void -print_iccp_header (iccHeader *icch, unsigned char *checksum) -{ - int i; - - ASSERT(icch); - -#define print_iccSig(s,t) if ((s) == 0) {\ - MESG("pdf_color>> %s:\t(null)\n", (t)); \ - } else if (!isprint(((s) >> 24) & 0xff) || \ - !isprint(((s) >> 16) & 0xff) || \ - !isprint(((s) >> 8) & 0xff) || \ - !isprint((s) & 0xff)) { \ - MESG("pdf_color>> %s:\t(invalid)\n", (t)); \ - } else { \ - MESG("pdf_color>> %s:\t%c%c%c%c\n", (t), \ - ((s) >> 24) & 0xff, ((s) >> 16) & 0xff, \ - ((s) >> 8) & 0xff, (s) & 0xff); \ -} - - MESG("\n"); - MESG("pdf_color>> ICC Profile Info\n"); - MESG("pdf_color>> Profile Size:\t%ld bytes\n", icch->size); - print_iccSig(icch->CMMType, "CMM Type"); - MESG("pdf_color>> Profile Version:\t%d.%01d.%01d\n", - (icch->version >> 24) & 0xff, - (icch->version >> 20) & 0x0f, - (icch->version >> 16) & 0x0f); - print_iccSig(icch->devClass, "Device Class"); - print_iccSig(icch->colorSpace, "Color Space"); - print_iccSig(icch->PCS, "Connection Space"); - MESG("pdf_color>> Creation Date:\t"); - for (i = 0; i < 12; i += 2) { - if (i == 0) - MESG("%04u", - sget_unsigned_pair((unsigned char *) icch->creationDate)); - else { - MESG(":%02u", - sget_unsigned_pair((unsigned char *) (&icch->creationDate[i]))); - } - } - MESG("\n"); - print_iccSig(icch->platform, "Primary Platform"); - MESG("pdf_color>> Profile Flags:\t%02x:%02x:%02x:%02x\n", - icch->flags[0], icch->flags[1], icch->flags[2], icch->flags[3]); - print_iccSig(icch->devMnfct, "Device Mnfct"); - print_iccSig(icch->devModel, "Device Model"); - MESG("pdf_color>> Device Attr:\t"); - for (i = 0; i < 8; i++) { - if (i == 0) - MESG("%02x", icch->devAttr[i]); - else - MESG(":%02x", icch->devAttr[i]); - } - MESG("\n"); - MESG("pdf_color>> Rendering Intent:\t"); - switch (ICC_INTENT_TYPE(icch->intent)) { - case ICC_INTENT_SATURATION: - MESG("Saturation"); - break; - case ICC_INTENT_PERCEPTUAL: - MESG("Perceptual"); - break; - case ICC_INTENT_ABSOLUTE: - MESG("Absolute Colorimetric"); - break; - case ICC_INTENT_RELATIVE: - MESG("Relative Colorimetric"); - break; - default: - MESG("(invalid)"); - break; - } - MESG("\n"); - print_iccSig(icch->creator, "Creator"); - MESG("pdf_color>> Illuminant (XYZ):\t"); - MESG("%.3f %.3f %.3f\n", - (double) icch->illuminant.X / 0x10000, - (double) icch->illuminant.Y / 0x10000, - (double) icch->illuminant.Z / 0x10000); - MESG("pdf_color>> Checksum:\t"); - if (!memcmp(icch->ID, nullbytes16, 16)) { - MESG("(null)"); - } else { - for (i = 0; i < 16; i++) { - if (i == 0) - MESG("%02x", icch->ID[i]); - else - MESG(":%02x", icch->ID[i]); - } - } - MESG("\n"); - if (checksum) { - MESG("pdf_color>> Calculated:\t"); - for (i = 0; i < 16; i++) { - if (i == 0) - MESG("%02x", checksum[i]); - else - MESG(":%02x", checksum[i]); - } - MESG("\n"); - } - - return; -} - - -static int -iccp_devClass_allowed (int dev_class) -{ - int colormode; - - colormode = pdf_dev_get_param(PDF_DEV_PARAM_COLORMODE); - - switch (colormode) { -#if 0 - case PDF_DEV_COLORMODE_PDFX1: - break; - case PDF_DEV_COLORMODE_PDFX3: - if (dev_class != str2iccSig("prtr")) { - return 0; - } - break; -#endif - default: - if (dev_class != str2iccSig("scnr") && - dev_class != str2iccSig("mntr") && - dev_class != str2iccSig("prtr") && - dev_class != str2iccSig("spac")) { - return 0; - } - break; - } - - - return 1; -} - -int -iccp_load_profile (const char *ident, - const void *profile, long proflen) -{ - int cspc_id; - pdf_obj *resource; - pdf_obj *stream; - pdf_obj *stream_dict; - iccHeader icch; - int colorspace; - unsigned char checksum[16]; - struct iccbased_cdata *cdata; - - iccp_init_iccHeader(&icch); - if (iccp_unpack_header(&icch, profile, proflen, 1) < 0) { /* check size */ - WARN("Invalid ICC profile header in \"%s\"", ident); - print_iccp_header(&icch, NULL); - return -1; - } - - if (!iccp_version_supported((icch.version >> 24) & 0xff, - (icch.version >> 16) & 0xff)) { - WARN("ICC profile format spec. version %d.%01d.%01d" - " not supported in current PDF version setting.", - (icch.version >> 24) & 0xff, - (icch.version >> 20) & 0x0f, - (icch.version >> 16) & 0x0f); - WARN("ICC profile not embedded."); - print_iccp_header(&icch, NULL); - return -1; - } - - if (!iccp_devClass_allowed(icch.devClass)) { - WARN("Unsupported ICC Profile Device Class:"); - print_iccp_header(&icch, NULL); - return -1; - } - - if (icch.colorSpace == str2iccSig("RGB ")) { - colorspace = PDF_COLORSPACE_TYPE_RGB; - } else if (icch.colorSpace == str2iccSig("GRAY")) { - colorspace = PDF_COLORSPACE_TYPE_GRAY; - } else if (icch.colorSpace == str2iccSig("CMYK")) { - colorspace = PDF_COLORSPACE_TYPE_CMYK; - } else { - WARN("Unsupported input color space."); - print_iccp_header(&icch, NULL); - return -1; - } - - iccp_get_checksum(checksum, profile, proflen); - if (memcmp(icch.ID, nullbytes16, 16) && - memcmp(icch.ID, checksum, 16)) { - WARN("Invalid ICC profile: Inconsistent checksum."); - print_iccp_header(&icch, checksum); - return -1; - } - - cdata = NEW(1, struct iccbased_cdata); - init_iccbased_cdata(cdata); - cdata->colorspace = colorspace; - memcpy(cdata->checksum, checksum, 16); - - cspc_id = pdf_colorspace_findresource(ident, - PDF_COLORSPACE_TYPE_ICCBASED, cdata); - if (cspc_id >= 0) { - if (verbose) - MESG("(ICCP:[id=%d])", cspc_id); - release_iccbased_cdata(cdata); - return cspc_id; - } - if (verbose > 1) { - print_iccp_header(&icch, checksum); - } - - resource = pdf_new_array(); - - stream = pdf_new_stream(STREAM_COMPRESS); - pdf_add_array(resource, pdf_new_name("ICCBased")); - pdf_add_array(resource, pdf_ref_obj (stream)); - - stream_dict = pdf_stream_dict(stream); - pdf_add_dict(stream_dict, pdf_new_name("N"), - pdf_new_number(get_num_components_iccbased(cdata))); - - pdf_add_stream (stream, profile, proflen); - pdf_release_obj(stream); - - cspc_id = pdf_colorspace_defineresource(ident, - PDF_COLORSPACE_TYPE_ICCBASED, - cdata, resource); - - return cspc_id; -} - -#ifdef XETEX -#define WBUF_SIZE 4096 -static unsigned char wbuf[WBUF_SIZE]; - -static pdf_obj * -iccp_load_file_stream (unsigned char *checksum, long length, FILE *fp) -{ - pdf_obj *stream; - MD5_CONTEXT md5; - long nb_read; - - rewind(fp); - - if (fread(wbuf, 1, 128, fp) != 128) { - return NULL; - } - length -= 128; - - stream = pdf_new_stream(STREAM_COMPRESS); - - MD5_init (&md5); - MD5_write(&md5, wbuf + ICC_HEAD_SECT1_START, ICC_HEAD_SECT1_LENGTH); - MD5_write(&md5, nullbytes16, 12); - MD5_write(&md5, wbuf + ICC_HEAD_SECT2_START, ICC_HEAD_SECT2_LENGTH); - MD5_write(&md5, nullbytes16, 16); - MD5_write(&md5, wbuf + ICC_HEAD_SECT3_START, ICC_HEAD_SECT3_LENGTH); - - pdf_add_stream(stream, wbuf, 128); - - /* body */ - while (length > 0) { - nb_read = fread(wbuf, 1, MIN(length, WBUF_SIZE), fp); - MD5_write(&md5, wbuf, nb_read); - pdf_add_stream(stream, wbuf, nb_read); - length -= nb_read; - } - - MD5_final(checksum, &md5); - - - return stream; -} - -int -pdf_colorspace_load_ICCBased (const char *ident, const char *filename) -{ - int cspc_id; - FILE *fp; - pdf_obj *resource; - pdf_obj *stream; - pdf_obj *stream_dict; - iccHeader icch; - int colorspace; - long size; - unsigned char checksum[16]; - struct iccbased_cdata *cdata; - - - fp = DPXFOPEN(filename, DPX_RES_TYPE_ICCPROFILE); - if (!fp) - return -1; - - size = file_size(fp); - if (size < 128) { - MFCLOSE(fp); - return -1; - } - if (fread(wbuf, 1, 128, fp) != 128) { - DPXFCLOSE(fp); - return -1; - } - - iccp_init_iccHeader(&icch); - if (iccp_unpack_header(&icch, wbuf, 128, 0) < 0) { - WARN("Invalid ICC profile header in \"%s\"", ident); - print_iccp_header(&icch, NULL); - DPXFCLOSE(fp); - return -1; - } - if (icch.size > size) { - WARN("File size smaller than recorded in header: %ld %ld", - icch.size, size); - DPXFCLOSE(fp); - return -1; - } - - if (!iccp_version_supported((icch.version >> 24) & 0xff, - (icch.version >> 16) & 0xff)) { - WARN("ICC profile format spec. version %d.%01d.%01d" - " not supported in current PDF version setting.", - (icch.version >> 24) & 0xff, - (icch.version >> 20) & 0x0f, - (icch.version >> 16) & 0x0f); - WARN("ICC profile not embedded."); - print_iccp_header(&icch, NULL); - DPXFCLOSE(fp); - return -1; - } - - if (!iccp_devClass_allowed(icch.devClass)) { - WARN("Unsupported ICC Profile Device Class:"); - print_iccp_header(&icch, NULL); - DPXFCLOSE(fp); - return -1; - } - - if (icch.colorSpace == str2iccSig("RGB ")) { - colorspace = PDF_COLORSPACE_TYPE_RGB; - } else if (icch.colorSpace == str2iccSig("GRAY")) { - colorspace = PDF_COLORSPACE_TYPE_GRAY; - } else if (icch.colorSpace == str2iccSig("CMYK")) { - colorspace = PDF_COLORSPACE_TYPE_CMYK; - } else { - WARN("Unsupported input color space."); - print_iccp_header(&icch, NULL); - DPXFCLOSE(fp); - return -1; - } - - stream = iccp_load_file_stream(checksum, icch.size, fp); - DPXFCLOSE(fp); - - if (!stream) { - WARN("Loading ICC Profile failed...: %s", filename); - return -1; - } - - if (memcmp(icch.ID, nullbytes16, 16) && - memcmp(icch.ID, checksum, 16)) { - WARN("Invalid ICC profile: Inconsistent checksum."); - print_iccp_header(&icch, NULL); - pdf_release_obj(stream); - return -1; - } - - cdata = NEW(1, struct iccbased_cdata); - init_iccbased_cdata(cdata); - cdata->colorspace = colorspace; - memcpy(cdata->checksum, checksum, 16); - - cspc_id = pdf_colorspace_findresource(ident, - PDF_COLORSPACE_TYPE_ICCBASED, cdata); - if (cspc_id >= 0) { - if (verbose) - MESG("(ICCP:[id=%d])", cspc_id); - release_iccbased_cdata(cdata); - pdf_release_obj(stream); - return cspc_id; - } - if (verbose > 1) { - print_iccp_header(&icch, checksum); - } - - resource = pdf_new_array(); - - pdf_add_array(resource, pdf_new_name("ICCBased")); - pdf_add_array(resource, pdf_ref_obj (stream)); - - stream_dict = pdf_stream_dict(stream); - pdf_add_dict(stream_dict, pdf_new_name("N"), - pdf_new_number(get_num_components_iccbased(cdata))); - pdf_release_obj(stream); - - cspc_id = pdf_colorspace_defineresource(ident, - PDF_COLORSPACE_TYPE_ICCBASED, - cdata, resource); - - return cspc_id; -} -#endif - -typedef struct { - char *ident; - int subtype; - - pdf_obj *resource; - pdf_obj *reference; - - void *cdata; -} pdf_colorspace; - -static struct { - int count; - int capacity; - pdf_colorspace *colorspaces; -} cspc_cache = { - 0, 0, NULL -}; - -int -pdf_colorspace_findresource (const char *ident, - int type, const void *cdata) -{ - pdf_colorspace *colorspace; - int cspc_id, cmp = -1; - - for (cspc_id = 0; - cmp && cspc_id < cspc_cache.count; cspc_id++) { - colorspace = &cspc_cache.colorspaces[cspc_id]; - if (colorspace->subtype != type) - continue; - - switch (colorspace->subtype) { - case PDF_COLORSPACE_TYPE_ICCBASED: - cmp = compare_iccbased(ident, cdata, - colorspace->ident, colorspace->cdata); - break; - } - if (!cmp) - return cspc_id; - } - - return -1; /* not found */ -} - -static void -pdf_init_colorspace_struct (pdf_colorspace *colorspace) -{ - ASSERT(colorspace); - - colorspace->ident = NULL; - colorspace->subtype = PDF_COLORSPACE_TYPE_INVALID; - - colorspace->resource = NULL; - colorspace->reference = NULL; - colorspace->cdata = NULL; - - return; -} - -static void -pdf_clean_colorspace_struct (pdf_colorspace *colorspace) -{ - ASSERT(colorspace); - - if (colorspace->ident) - RELEASE(colorspace->ident); - if (colorspace->resource) - pdf_release_obj(colorspace->resource); - if (colorspace->reference) - pdf_release_obj(colorspace->reference); - colorspace->resource = NULL; - colorspace->reference = NULL; - - if (colorspace->cdata) { - switch (colorspace->subtype) { - case PDF_COLORSPACE_TYPE_ICCBASED: - release_iccbased_cdata(colorspace->cdata); - break; - } - } - colorspace->cdata = NULL; - colorspace->subtype = PDF_COLORSPACE_TYPE_INVALID; - - return; -} - -static void -pdf_flush_colorspace (pdf_colorspace *colorspace) -{ - ASSERT(colorspace); - - if (colorspace->resource) - pdf_release_obj(colorspace->resource); - if (colorspace->reference) - pdf_release_obj(colorspace->reference); - - colorspace->resource = NULL; - colorspace->reference = NULL; -} - -int -pdf_colorspace_defineresource (const char *ident, - int subtype, void *cdata, pdf_obj *resource) -{ - int cspc_id; - pdf_colorspace *colorspace; - - if (cspc_cache.count >= cspc_cache.capacity) { - cspc_cache.capacity += 16; - cspc_cache.colorspaces = RENEW(cspc_cache.colorspaces, - cspc_cache.capacity, pdf_colorspace); - } - cspc_id = cspc_cache.count; - colorspace = &cspc_cache.colorspaces[cspc_id]; - - pdf_init_colorspace_struct(colorspace); - if (ident) { - colorspace->ident = NEW(strlen(ident) + 1, char); - strcpy(colorspace->ident, ident); - } - colorspace->subtype = subtype; - colorspace->cdata = cdata; - colorspace->resource = resource; - - if (verbose) { - MESG("(ColorSpace:%s", ident); - if (verbose > 1) { - switch (subtype) { - case PDF_COLORSPACE_TYPE_ICCBASED: - MESG("[ICCBased]"); - break; - case PDF_COLORSPACE_TYPE_CALRGB: - MESG("[CalRGB]"); - break; - case PDF_COLORSPACE_TYPE_CALGRAY: - MESG("[CalGray]"); - break; - } - } - MESG(")"); - } - - cspc_cache.count++; - - return cspc_id; -} - -pdf_obj * -pdf_get_colorspace_reference (int cspc_id) -{ - pdf_colorspace *colorspace; - - colorspace = &cspc_cache.colorspaces[cspc_id]; - if (!colorspace->reference) { - colorspace->reference = pdf_ref_obj(colorspace->resource); - pdf_release_obj(colorspace->resource); /* .... */ - colorspace->resource = NULL; - } - - return pdf_link_obj(colorspace->reference); -} - -#if 0 -int -pdf_get_colorspace_num_components (int cspc_id) -{ - pdf_colorspace *colorspace; - int num_components; - - colorspace = &cspc_cache.colorspaces[cspc_id]; - - switch (colorspace->subtype) { - case PDF_COLORSPACE_TYPE_ICCBASED: - num_components = get_num_components_iccbased(colorspace->cdata); - break; - case PDF_COLORSPACE_TYPE_DEVICEGRAY: - num_components = 1; - break; - case PDF_COLORSPACE_TYPE_DEVICERGB: - num_components = 3; - break; - case PDF_COLORSPACE_TYPE_DEVICECMYK: - num_components = 4; - break; - case PDF_COLORSPACE_TYPE_CALRGB: - num_components = 3; - break; - case PDF_COLORSPACE_TYPE_CALGRAY: - num_components = 1; - break; - default: - num_components = 0; - break; - } - - return num_components; -} - -int -pdf_get_colorspace_subtype (int cspc_id) -{ - pdf_colorspace *colorspace; - - colorspace = &cspc_cache.colorspaces[cspc_id]; - - return colorspace->subtype; -} -#endif - -void -pdf_init_colors (void) -{ - cspc_cache.count = 0; - cspc_cache.capacity = 0; - cspc_cache.colorspaces = NULL; -} - -void -pdf_close_colors (void) -{ - int i; - - for (i = 0; i < cspc_cache.count; i++) { - pdf_colorspace *colorspace; - - colorspace = &cspc_cache.colorspaces[i]; - pdf_flush_colorspace(colorspace); - pdf_clean_colorspace_struct(colorspace); - } - RELEASE(cspc_cache.colorspaces); - cspc_cache.colorspaces = NULL; - cspc_cache.count = cspc_cache.capacity = 0; - -} - -#define PDF_COLORSPACE_FAMILY_DEVICE 0 -#define PDF_COLORSPACE_FAMILY_CIEBASED 1 -#define PDF_COLORSPACE_FAMILY_SPECIAL 2 |