summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKen Sharp <ken.sharp@artifex.com>2021-04-12 09:35:47 +0100
committerKen Sharp <ken.sharp@artifex.com>2021-04-12 09:35:47 +0100
commit7eb10d0b2f9f3b77a1cd56ba047040af970a296a (patch)
treed11ba4b6ee68d0d6c95985bceb61c4c16b69abad
parent8c3cf4c12535fe1ecadc5ee6a9b0c8a60de0e638 (diff)
parente9031002d8eefbf4d889fd66f41f80e99db988c2 (diff)
downloadghostpdl-7eb10d0b2f9f3b77a1cd56ba047040af970a296a.tar.gz
Merge branch 'master' into pdfi
-rw-r--r--Resource/Init/pdf_draw.ps6
-rw-r--r--base/gsicc_profilecache.c6
-rw-r--r--base/tesseract.mak6
-rw-r--r--configure.ac2
-rw-r--r--contrib/eplaser/gdevescv.c18
-rw-r--r--devices/gxfcopy.c4
-rw-r--r--lib/ghostpdf.catbin7290 -> 7741 bytes
-rw-r--r--psi/msvc.mak2
-rw-r--r--psi/zcharout.c20
-rw-r--r--psi/zcie.c20
-rw-r--r--psi/zcolor.c145
-rw-r--r--psi/zicc.c6
12 files changed, 212 insertions, 23 deletions
diff --git a/Resource/Init/pdf_draw.ps b/Resource/Init/pdf_draw.ps
index f6395a933..fe43e269c 100644
--- a/Resource/Init/pdf_draw.ps
+++ b/Resource/Init/pdf_draw.ps
@@ -1758,14 +1758,16 @@ currentdict /jp2_csp_dict .undef
% <resdict> <key> <value> -> <resdict>
/add-to-last-param {
2 index /DecodeParms knownoget {
- dup {} eq {
+ dup type /dicttype ne 1 index type /arrratype ne and 1 index length 1 lt or {
pop //false
} {
//true
} ifelse
} {
//false
- } ifelse {
+ }
+ ifelse
+ {
dup type /arraytype eq {
[ exch { oforce } forall
dup //null eq { pop 1 dict } if
diff --git a/base/gsicc_profilecache.c b/base/gsicc_profilecache.c
index db2e8ae4a..900a3440b 100644
--- a/base/gsicc_profilecache.c
+++ b/base/gsicc_profilecache.c
@@ -95,6 +95,9 @@ gsicc_add_cs(gs_gstate * pgs, gs_color_space * colorspace, uint64_t dictkey)
gsicc_profile_cache_t *profile_cache = pgs->icc_profile_cache;
gs_memory_t *memory = pgs->memory;
+ if (dictkey == 0)
+ return;
+
/* The entry has to be added in stable memory. We want them
to be maintained across the gsave and grestore process */
result = gs_alloc_struct(memory->stable_memory, gsicc_profile_entry_t,
@@ -125,6 +128,9 @@ gsicc_find_cs(uint64_t key_test, gs_gstate * pgs)
gsicc_profile_cache_t *profile_cache = pgs->icc_profile_cache;
gsicc_profile_entry_t *prev = NULL, *curr = profile_cache->head;
+ if (key_test == 0)
+ return NULL;
+
/* Look through the cache for the key. If found, move to MRU */
while (curr != NULL ){
if (curr->key == key_test){
diff --git a/base/tesseract.mak b/base/tesseract.mak
index 9971c87bf..d9fcb7a81 100644
--- a/base/tesseract.mak
+++ b/base/tesseract.mak
@@ -24,7 +24,11 @@ TESSINCLUDES=\
# add -DDISABLED_LEGACY_ENGINE to TESSCXX
# empty TESSERACT_LEGACY
-TESSCXX = $(CXX) $(TESSINCLUDES) $(TESSCXXFLAGS) $(CCFLAGS) -DTESSERACT_IMAGEDATA_AS_PIX -DTESSERACT_DISABLE_DEBUG_FONTS -DGRAPHICS_DISABLED
+# We set -DCLUSTER when doing builds for our testing cluster. Unfortunately,
+# this conflicts with Tesseract's use of a CLUSTER type. We work around this
+# here by undefining CLUSTER for the tesseract portion of the build.
+
+TESSCXX = $(CXX) $(TESSINCLUDES) $(TESSCXXFLAGS) $(CCFLAGS) -DTESSERACT_IMAGEDATA_AS_PIX -DTESSERACT_DISABLE_DEBUG_FONTS -DGRAPHICS_DISABLED -UCLUSTER
#-DDISABLED_LEGACY_ENGINE
TESSOBJ = $(GLOBJDIR)$(D)tesseract_
TESSO_ = $(O_)$(TESSOBJ)
diff --git a/configure.ac b/configure.ac
index c70a7de08..72dbae64b 100644
--- a/configure.ac
+++ b/configure.ac
@@ -864,7 +864,7 @@ if test x$with_tesseract != xno; then
for flag in $cxxflags_to_try ; do
CXXFLAGS="$CXXFLAGS $flag"
- AC_TRY_COMPILE(, [return 0;], [
+ AC_TRY_COMPILE([#include <cstdlib>], [return 0;], [
echo " $flag"; CXXFLAGS_TO_USE="$CXXFLAGS_TO_USE $flag"
])
diff --git a/contrib/eplaser/gdevescv.c b/contrib/eplaser/gdevescv.c
index c7bd29e18..83248407d 100644
--- a/contrib/eplaser/gdevescv.c
+++ b/contrib/eplaser/gdevescv.c
@@ -35,17 +35,12 @@
#include <stdlib.h> /* for abs() and free */
-/* Get this definition in before we read memento.h */
-static void
-unvectored_free(void *x)
-{
- free(x);
-}
-
#if ( 6 > GS_VERSION_MAJOR )
#include <string.h>
+#ifndef _WIN32
#include <sys/utsname.h> /* for uname(2) */
+#endif
#include <ctype.h> /* for toupper(3) */
#include "math_.h"
@@ -68,7 +63,9 @@ unvectored_free(void *x)
#else /* 6 <= GS_VERSION_MAJOR */
#include "math_.h"
+#ifndef _WIN32
#include <sys/utsname.h> /* for uname(2) */
+#endif
#include <ctype.h> /* for toupper(3) */
#include "time_.h"
@@ -827,6 +824,9 @@ escv_checkpapersize(gx_device_vector * vdev)
static char *
get_sysname ( void )
{
+#ifdef _WIN32
+ return strdup("BOGUS");
+#else
char *result = NULL;
struct utsname utsn;
@@ -835,6 +835,7 @@ get_sysname ( void )
result = strdup (utsn.sysname);
}
return result;
+#endif
}
/* EPSON printer model name translation.
@@ -1032,8 +1033,7 @@ escv_beginpage(gx_device_vector * vdev)
if (sysname)
{
lputs(s, sysname );
- /* Carefully avoid memento interfering here. */
- unvectored_free(sysname);
+ free(sysname);
sysname = NULL;
}
}
diff --git a/devices/gxfcopy.c b/devices/gxfcopy.c
index 4f2ca6fd1..bfbcc3e15 100644
--- a/devices/gxfcopy.c
+++ b/devices/gxfcopy.c
@@ -2289,6 +2289,10 @@ int gs_free_copied_font(gs_font *font)
}
gs_free_object(mem, copied0->cidata.FDArray, "free copied CIDFont FDArray");
copied0->cidata.FDArray = 0;
+ gs_free_string(mem, (byte *)copied0->cidata.common.CIDSystemInfo.Registry.data, copied0->cidata.common.CIDSystemInfo.Registry.size, "Free copied Registry");
+ gs_free_string(mem, (byte *)copied0->cidata.common.CIDSystemInfo.Ordering.data, copied0->cidata.common.CIDSystemInfo.Ordering.size, "Free copied Registry");
+ copied0->cidata.common.CIDSystemInfo.Registry.data = copied0->cidata.common.CIDSystemInfo.Ordering.data = NULL;
+ copied0->cidata.common.CIDSystemInfo.Registry.size = copied0->cidata.common.CIDSystemInfo.Ordering.size = 0;
}
if (font->FontType == ft_CID_TrueType) {
diff --git a/lib/ghostpdf.cat b/lib/ghostpdf.cat
index 4c6fc3046..e0350d39c 100644
--- a/lib/ghostpdf.cat
+++ b/lib/ghostpdf.cat
Binary files differ
diff --git a/psi/msvc.mak b/psi/msvc.mak
index 0a8464538..63f4962af 100644
--- a/psi/msvc.mak
+++ b/psi/msvc.mak
@@ -1748,7 +1748,7 @@ DEVICE_DEVS19=$(DD)lbp8.dev $(DD)m8510.dev $(DD)necp6.dev $(DD)bjc600.dev $(DD)b
DEVICE_DEVS20=$(DD)pnm.dev $(DD)pnmraw.dev $(DD)ppm.dev $(DD)ppmraw.dev $(DD)pamcmyk32.dev $(DD)pamcmyk4.dev $(DD)pnmcmyk.dev $(DD)pam.dev
DEVICE_DEVS21=$(DD)spotcmyk.dev $(DD)devicen.dev $(DD)bmpsep1.dev $(DD)bmpsep8.dev $(DD)bmp16m.dev $(DD)bmp32b.dev $(DD)psdcmyk.dev $(DD)psdrgb.dev $(DD)psdcmyk16.dev $(DD)psdrgb16.dev
!endif
-CONTRIB_DEVS=$(DD)pcl3.dev $(DD)hpdjplus.dev $(DD)hpdjportable.dev $(DD)hpdj310.dev $(DD)hpdj320.dev $(DD)hpdj340.dev $(DD)hpdj400.dev $(DD)hpdj500.dev $(DD)hpdj500c.dev $(DD)hpdj510.dev $(DD)hpdj520.dev $(DD)hpdj540.dev $(DD)hpdj550c.dev $(DD)hpdj560c.dev $(DD)hpdj600.dev $(DD)hpdj660c.dev $(DD)hpdj670c.dev $(DD)hpdj680c.dev $(DD)hpdj690c.dev $(DD)hpdj850c.dev $(DD)hpdj855c.dev $(DD)hpdj870c.dev $(DD)hpdj890c.dev $(DD)hpdj1120c.dev $(DD)cdj670.dev $(DD)cdj850.dev $(DD)cdj880.dev $(DD)cdj890.dev $(DD)cdj970.dev $(DD)cdj1600.dev $(DD)cdnj500.dev $(DD)chp2200.dev $(DD)lips3.dev $(DD)lxm3200.dev $(DD)lex2050.dev $(DD)lxm3200.dev $(DD)lex5700.dev $(DD)lex7000.dev $(DD)oki4w.dev $(DD)gdi.dev $(DD)samsunggdi.dev $(DD)dl2100.dev $(DD)la50.dev $(DD)la70.dev $(DD)la75.dev $(DD)la75plus.dev $(DD)ln03.dev $(DD)xes.dev $(DD)md2k.dev $(DD)md5k.dev $(DD)lips4.dev $(DD)bj10v.dev $(DD)bj10vh.dev $(DD)md50Mono.dev $(DD)md50Eco.dev $(DD)md1xMono.dev $(DD)lp2000.dev $(DD)escpage.dev $(DD)npdl.dev $(DD)rpdl.dev $(DD)fmpr.dev $(DD)fmlbp.dev $(DD)jj100.dev $(DD)lbp310.dev $(DD)lbp320.dev $(DD)mj700v2c.dev $(DD)mj500c.dev $(DD)mj6000c.dev $(DD)mj8000c.dev $(DD)pr201.dev $(DD)pr150.dev $(DD)pr1000.dev $(DD)pr1000_4.dev $(DD)lips2p.dev $(DD)bjc880j.dev $(DD)bjcmono.dev $(DD)bjcgray.dev $(DD)bjccmyk.dev $(DD)bjccolor.dev
+CONTRIB_DEVS=$(DD)pcl3.dev $(DD)hpdjplus.dev $(DD)hpdjportable.dev $(DD)hpdj310.dev $(DD)hpdj320.dev $(DD)hpdj340.dev $(DD)hpdj400.dev $(DD)hpdj500.dev $(DD)hpdj500c.dev $(DD)hpdj510.dev $(DD)hpdj520.dev $(DD)hpdj540.dev $(DD)hpdj550c.dev $(DD)hpdj560c.dev $(DD)hpdj600.dev $(DD)hpdj660c.dev $(DD)hpdj670c.dev $(DD)hpdj680c.dev $(DD)hpdj690c.dev $(DD)hpdj850c.dev $(DD)hpdj855c.dev $(DD)hpdj870c.dev $(DD)hpdj890c.dev $(DD)hpdj1120c.dev $(DD)cdj670.dev $(DD)cdj850.dev $(DD)cdj880.dev $(DD)cdj890.dev $(DD)cdj970.dev $(DD)cdj1600.dev $(DD)cdnj500.dev $(DD)chp2200.dev $(DD)lips3.dev $(DD)lxm3200.dev $(DD)lex2050.dev $(DD)lxm3200.dev $(DD)lex5700.dev $(DD)lex7000.dev $(DD)oki4w.dev $(DD)gdi.dev $(DD)samsunggdi.dev $(DD)dl2100.dev $(DD)la50.dev $(DD)la70.dev $(DD)la75.dev $(DD)la75plus.dev $(DD)ln03.dev $(DD)xes.dev $(DD)md2k.dev $(DD)md5k.dev $(DD)lips4.dev $(DD)bj10v.dev $(DD)bj10vh.dev $(DD)md50Mono.dev $(DD)md50Eco.dev $(DD)md1xMono.dev $(DD)lp2000.dev $(DD)escpage.dev $(DD)npdl.dev $(DD)rpdl.dev $(DD)fmpr.dev $(DD)fmlbp.dev $(DD)jj100.dev $(DD)lbp310.dev $(DD)lbp320.dev $(DD)mj700v2c.dev $(DD)mj500c.dev $(DD)mj6000c.dev $(DD)mj8000c.dev $(DD)pr201.dev $(DD)pr150.dev $(DD)pr1000.dev $(DD)pr1000_4.dev $(DD)lips2p.dev $(DD)bjc880j.dev $(DD)bjcmono.dev $(DD)bjcgray.dev $(DD)bjccmyk.dev $(DD)bjccolor.dev $(DD)escp.dev $(DD)lp8000.dev $(DD)lq850.dev $(DD)photoex.dev $(DD)st800.dev $(DD)stcolor.dev $(DD)alc1900.dev $(DD)alc2000.dev $(DD)alc4000.dev $(DD)alc4100.dev $(DD)alc8500.dev $(DD)alc8600.dev $(DD)alc9100.dev $(DD)lp3000c.dev $(DD)lp8000c.dev $(DD)lp8200c.dev $(DD)lp8300c.dev $(DD)lp8500c.dev $(DD)lp8800c.dev $(DD)lp9000c.dev $(DD)lp9200c.dev $(DD)lp9500c.dev $(DD)lp9800c.dev $(DD)lps6500.dev $(DD)epl2050.dev $(DD)epl2050p.dev $(DD)epl2120.dev $(DD)epl2500.dev $(DD)epl2750.dev $(DD)epl5800.dev $(DD)epl5900.dev $(DD)epl6100.dev $(DD)epl6200.dev $(DD)lp1800.dev $(DD)lp1900.dev $(DD)lp2200.dev $(DD)lp2400.dev $(DD)lp2500.dev $(DD)lp7500.dev $(DD)lp7700.dev $(DD)lp7900.dev $(DD)lp8100.dev $(DD)lp8300f.dev $(DD)lp8400f.dev $(DD)lp8600.dev $(DD)lp8600f.dev $(DD)lp8700.dev $(DD)lp8900.dev $(DD)lp9000b.dev $(DD)lp9100.dev $(DD)lp9200b.dev $(DD)lp9300.dev $(DD)lp9400.dev $(DD)lp9600.dev $(DD)lp9600s.dev $(DD)lps4500.dev $(DD)eplcolor.dev $(DD)eplmono.dev
!if "$(WITH_CONTRIB)" == "1"
DEVICE_DEVS16=$(DEVICE_DEVS16) $(CONTRIB_DEVS)
diff --git a/psi/zcharout.c b/psi/zcharout.c
index 42f8ebbb2..c204a9566 100644
--- a/psi/zcharout.c
+++ b/psi/zcharout.c
@@ -326,8 +326,26 @@ zchar_charstring_data(gs_font *font, const ref *pgref, gs_glyph_data_t *pgd)
charstring_is_notdef_proc(font->memory, pcstr)
)
return charstring_make_notdef(pgd, font);
- else
+ else {
+ /* Bug #703779. It seems that other tools can modify type 1 fonts, using
+ * a procedure in place of a CharString for the /.notdef. In this case the
+ * culprit is "Polylogics DIAD White Pages Pagination". Doing this prevents
+ * pdfwrite from being able to write the font. Obviously we cannot have a
+ * PostScript procedure in a PDF file. Adobe Acrobat Distiller replaces
+ * the procedure with a simple 'endchar' CharString, so we now do the
+ * same. I've chosen to leave the specific ADOBEPS4 test above unchanged, rather
+ * than roll it in here, because I can't find an example file for it and
+ * can't be certain that 'pgref' will be a name in that case.
+ */
+ ref namestr;
+
+ if (r_has_type(pgref, t_name)) {
+ name_string_ref(pgd->memory, pgref, &namestr);
+ if (r_size(&namestr) == 7 && !memcmp(namestr.value.bytes, ".notdef", 7))
+ return charstring_make_notdef(pgd, font);
+ }
return_error(gs_error_typecheck);
+ }
}
gs_glyph_data_from_string(pgd, pcstr->value.const_bytes, r_size(pcstr),
NULL);
diff --git a/psi/zcie.c b/psi/zcie.c
index 616b4b718..57f92f800 100644
--- a/psi/zcie.c
+++ b/psi/zcie.c
@@ -448,8 +448,11 @@ ciedefgspace(i_ctx_t *i_ctx_p, ref *CIEDict, uint64_t dictkey)
bool has_defg_procs, has_abc_procs, has_lmn_procs;
gs_ref_memory_t *imem = (gs_ref_memory_t *)mem;
- if (dictkey != 0)
+ if (dictkey != 0) {
pcs = gsicc_find_cs(dictkey, igs);
+ if (pcs && gs_color_space_num_components(pcs) != 4)
+ pcs = NULL;
+ }
else
pcs = NULL;
push(1); /* Sacrificial */
@@ -558,8 +561,11 @@ ciedefspace(i_ctx_t *i_ctx_p, ref *CIEDict, uint64_t dictkey)
bool has_def_procs, has_lmn_procs, has_abc_procs;
gs_ref_memory_t *imem = (gs_ref_memory_t *)mem;
- if (dictkey != 0)
+ if (dictkey != 0) {
pcs = gsicc_find_cs(dictkey, igs);
+ if (pcs && gs_color_space_num_components(pcs) != 3)
+ pcs = NULL;
+ }
else
pcs = NULL;
push(1); /* Sacrificial */
@@ -626,8 +632,11 @@ cieabcspace(i_ctx_t *i_ctx_p, ref *CIEDict, uint64_t dictkey)
gs_ref_memory_t *imem = (gs_ref_memory_t *)mem;
/* See if the color space is in the profile cache */
- if (dictkey != 0)
+ if (dictkey != 0) {
pcs = gsicc_find_cs(dictkey, igs);
+ if (pcs && gs_color_space_num_components(pcs) != 3)
+ pcs = NULL;
+ }
else
pcs = NULL;
@@ -690,8 +699,11 @@ cieaspace(i_ctx_t *i_ctx_p, ref *CIEdict, uint64_t dictkey)
bool has_lmn_procs;
/* See if the color space is in the profile cache */
- if (dictkey != 0)
+ if (dictkey != 0) {
pcs = gsicc_find_cs(dictkey, igs);
+ if (pcs && gs_color_space_num_components(pcs) != 1)
+ pcs = NULL;
+ }
else
pcs = NULL;
push(1); /* Sacrificial */
diff --git a/psi/zcolor.c b/psi/zcolor.c
index 34a9326f3..0b71b934a 100644
--- a/psi/zcolor.c
+++ b/psi/zcolor.c
@@ -5519,6 +5519,60 @@ static int checkGamma(i_ctx_t * i_ctx_p, ref *CIEdict, int numvalues)
return 0;
}
+static int hashcalgrayspace(i_ctx_t *i_ctx_p, ref *space, gs_md5_state_t *md5)
+{
+ int code = 0;
+ ref cgdict1, spacename, *tempref;
+ static const int ncomps = 1;
+ float g = 1.0;
+ int i;
+
+ code = array_get(imemory, space, 0, &spacename);
+ if (code < 0)
+ return 0;
+ gs_md5_append(md5, (const gs_md5_byte_t *)&spacename.value.pname, sizeof(spacename.value.pname));
+
+ code = array_get(imemory, space, 1, &cgdict1);
+ if (code < 0)
+ return 0;
+ check_read_type(cgdict1, t_dictionary);
+
+ code = dict_find_string(&cgdict1, "WhitePoint", &tempref);
+ if (code > 0) {
+ code = hasharray(i_ctx_p, tempref, md5);
+ }
+ if (code <= 0) {
+ float WP = 0.0;
+ for (i = 0; i < 3; i++) {
+ gs_md5_append(md5, (const gs_md5_byte_t *)&WP, sizeof(WP));
+ }
+ }
+
+ code = dict_find_string(&cgdict1, "BlackPoint", &tempref);
+ if (code > 0) {
+ code = hasharray(i_ctx_p, tempref, md5);
+ }
+ if (code <= 0) {
+ float BP = 0.0;
+ for (i = 0; i < 3; i++) {
+ gs_md5_append(md5, (const gs_md5_byte_t *)&BP, sizeof(BP));
+ }
+ }
+
+ code = dict_find_string(&cgdict1, "Gamma", &tempref);
+ if (code > 0) {
+ if (r_has_type(tempref, t_real))
+ g = tempref->value.realval;
+ else if (r_has_type(tempref, t_integer))
+ g = (float)tempref->value.intval;
+ }
+
+ gs_md5_append(md5, (const gs_md5_byte_t *)&g, sizeof(g));
+
+ gs_md5_append(md5, (const gs_md5_byte_t *)&ncomps, sizeof(ncomps));
+ return 1;
+}
+
/* Here we set up an equivalent ICC form for the CalGray color space */
static int setcalgrayspace(i_ctx_t * i_ctx_p, ref *r, int *stage, int *cont, int CIESubst)
{
@@ -5528,6 +5582,9 @@ static int setcalgrayspace(i_ctx_t * i_ctx_p, ref *r, int *stage, int *cont, int
double dflt_gamma = 1.0;
static const float dflt_black[3] = {0,0,0}, dflt_white[3] = {0,0,0};
gs_client_color cc;
+ uint64_t dictkey = 0;
+ gs_md5_state_t md5;
+ byte key[16];
*cont = 0;
code = array_get(imemory, r, 1, &graydict);
@@ -5558,8 +5615,15 @@ static int setcalgrayspace(i_ctx_t * i_ctx_p, ref *r, int *stage, int *cont, int
return code;
if (white[0] <= 0 || white[1] != 1.0 || white[2] <= 0)
return_error(gs_error_rangecheck);
- code = seticc_cal(i_ctx_p, white, black, &gamma, NULL, 1,
- graydict.value.saveid);
+
+ gs_md5_init(&md5);
+ hashcalgrayspace(i_ctx_p, r, &md5);
+ gs_md5_finish(&md5, key);
+ if (code > 0) {
+ dictkey = *(uint64_t *)&key[sizeof(key) - sizeof(uint64_t)];
+ }
+
+ code = seticc_cal(i_ctx_p, white, black, &gamma, NULL, 1, dictkey);
if ( code < 0)
return gs_rethrow(code, "setting CalGray color space");
cc.pattern = 0x00;
@@ -5601,6 +5665,72 @@ static int validatecalgrayspace(i_ctx_t * i_ctx_p, ref **r)
return 0;
}
+static int hashcalrgbspace(i_ctx_t *i_ctx_p, ref *space, gs_md5_state_t *md5)
+{
+ int code = 0;
+ ref crgbdict1, spacename, *tempref;
+ static const int ncomps = 3;
+ int i;
+
+ code = array_get(imemory, space, 0, &spacename);
+ if (code < 0)
+ return 0;
+ gs_md5_append(md5, (const gs_md5_byte_t *)&spacename.value.pname, sizeof(spacename.value.pname));
+
+ code = array_get(imemory, space, 1, &crgbdict1);
+ if (code < 0)
+ return 0;
+ check_read_type(crgbdict1, t_dictionary);
+
+ code = dict_find_string(&crgbdict1, "WhitePoint", &tempref);
+ if (code > 0) {
+ code = hasharray(i_ctx_p, tempref, md5);
+ }
+ if (code <= 0) {
+ float WP = 0.0;
+ for (i = 0; i < 3; i++) {
+ gs_md5_append(md5, (const gs_md5_byte_t *)&WP, sizeof(WP));
+ }
+ }
+
+ code = dict_find_string(&crgbdict1, "BlackPoint", &tempref);
+ if (code > 0) {
+ code = hasharray(i_ctx_p, tempref, md5);
+ }
+ if (code <= 0) {
+ float BP = 0.0;
+ for (i = 0; i < 3; i++) {
+ gs_md5_append(md5, (const gs_md5_byte_t *)&BP, sizeof(BP));
+ }
+ }
+
+ code = dict_find_string(&crgbdict1, "Matrix", &tempref);
+ if (code > 0) {
+ code = hasharray(i_ctx_p, tempref, md5);
+ }
+ if (code <= 0) {
+ static const float mt[9] = {1,0,0,0,1,0,0,0,1};
+
+ for (i = 0; i < 9; i++) {
+ gs_md5_append(md5, (const gs_md5_byte_t *)&(mt[i]), sizeof(mt[i]));
+ }
+ }
+
+ code = dict_find_string(&crgbdict1, "Gamma", &tempref);
+ if (code > 0) {
+ code = hasharray(i_ctx_p, tempref, md5);
+ }
+ if (code <= 0) {
+ static const float g[3] = { 1.0, 1.0, 1.0 };
+ for (i = 0; i < 3; i++) {
+ gs_md5_append(md5, (const gs_md5_byte_t *)&(g[i]), sizeof(g[i]));
+ }
+ }
+
+ gs_md5_append(md5, (const gs_md5_byte_t *)&ncomps, sizeof(ncomps));
+ return 1;
+}
+
/* Here we set up an equivalent ICC form for the CalRGB color space */
static int setcalrgbspace(i_ctx_t * i_ctx_p, ref *r, int *stage, int *cont, int CIESubst)
{
@@ -5612,6 +5742,9 @@ static int setcalrgbspace(i_ctx_t * i_ctx_p, ref *r, int *stage, int *cont, int
static const float dflt_matrix[9] = {1,0,0,0,1,0,0,0,1};
int i;
gs_client_color cc;
+ uint64_t dictkey = 0;
+ gs_md5_state_t md5;
+ byte key[16];
*cont = 0;
code = array_get(imemory, r, 1, &rgbdict);
@@ -5654,7 +5787,13 @@ static int setcalrgbspace(i_ctx_t * i_ctx_p, ref *r, int *stage, int *cont, int
dflt_matrix );
if (code < 0)
return code;
- code = seticc_cal(i_ctx_p, white, black, gamma, matrix, 3, rgbdict.value.saveid);
+ gs_md5_init(&md5);
+ hashcalrgbspace(i_ctx_p, r, &md5);
+ gs_md5_finish(&md5, key);
+ if (code > 0) {
+ dictkey = *(uint64_t *)&key[sizeof(key) - sizeof(uint64_t)];
+ }
+ code = seticc_cal(i_ctx_p, white, black, gamma, matrix, 3, dictkey);
if ( code < 0)
return gs_rethrow(code, "setting CalRGB color space");
cc.pattern = 0x00;
diff --git a/psi/zicc.c b/psi/zicc.c
index e01913eb1..91f1c41c9 100644
--- a/psi/zicc.c
+++ b/psi/zicc.c
@@ -64,7 +64,7 @@ int seticc(i_ctx_t * i_ctx_p, int ncomps, ref *ICCdict, float *range_buff)
dict_find_string(ICCdict, ".hash", &phashval) == 1 &&
r_has_type(phashval, t_integer)) {
pcs = gsicc_find_cs(phashval->value.intval, igs);
- if (pcs != NULL) {
+ if (pcs != NULL && gs_color_space_num_components(pcs) == ncomps) {
/* Set the color space. We are done. */
code = gs_setcolorspace(igs, pcs);
/* Remove the ICC dict from the stack */
@@ -468,6 +468,10 @@ seticc_cal(i_ctx_t * i_ctx_p, float *white, float *black, float *gamma,
/* See if the color space is in the profile cache */
pcs = gsicc_find_cs(dictkey, igs);
+ if (pcs != NULL && gs_color_space_num_components(pcs) != num_colorants) {
+ pcs = NULL;
+ dictkey = 0;
+ }
if (pcs == NULL ) {
/* build the color space object. Since this is cached
in the profile cache which is a member variable