diff options
author | Robin Watts <Robin.Watts@artifex.com> | 2021-02-17 16:04:27 +0000 |
---|---|---|
committer | Robin Watts <Robin.Watts@artifex.com> | 2021-02-17 16:55:05 +0000 |
commit | 82dce7f8f6b5218f7943eadff0f01d0e278850fa (patch) | |
tree | 7cd334c4ce1fb378ba535dc172c9957d5a5c3982 /lcms2mt/src | |
parent | 5882f2d765a9348c6f6e2cc45353a06924930c88 (diff) | |
download | ghostpdl-82dce7f8f6b5218f7943eadff0f01d0e278850fa.tar.gz |
Update lcms2mt to lcms2 2.12.
Diffstat (limited to 'lcms2mt/src')
-rw-r--r-- | lcms2mt/src/Makefile.in | 148 | ||||
-rw-r--r-- | lcms2mt/src/cmsalpha.c | 27 | ||||
-rw-r--r-- | lcms2mt/src/cmscgats.c | 21 | ||||
-rw-r--r-- | lcms2mt/src/cmscnvrt.c | 93 | ||||
-rw-r--r-- | lcms2mt/src/cmsgamma.c | 76 | ||||
-rw-r--r-- | lcms2mt/src/cmsintrp.c | 534 | ||||
-rw-r--r-- | lcms2mt/src/cmsio0.c | 31 | ||||
-rw-r--r-- | lcms2mt/src/cmslut.c | 12 | ||||
-rw-r--r-- | lcms2mt/src/cmsnamed.c | 20 | ||||
-rw-r--r-- | lcms2mt/src/cmsopt.c | 28 | ||||
-rw-r--r-- | lcms2mt/src/cmspack.c | 2 | ||||
-rw-r--r-- | lcms2mt/src/cmspcs.c | 2 | ||||
-rw-r--r-- | lcms2mt/src/cmsplugin.c | 39 | ||||
-rw-r--r-- | lcms2mt/src/cmsps2.c | 11 | ||||
-rw-r--r-- | lcms2mt/src/cmssamp.c | 4 | ||||
-rw-r--r-- | lcms2mt/src/cmstypes.c | 20 | ||||
-rw-r--r-- | lcms2mt/src/cmsxform.c | 89 | ||||
-rw-r--r-- | lcms2mt/src/extra_xform.h | 4 | ||||
-rw-r--r-- | lcms2mt/src/lcms2_internal.h | 28 | ||||
-rw-r--r-- | lcms2mt/src/lcms2mt.def | 1 |
20 files changed, 537 insertions, 653 deletions
diff --git a/lcms2mt/src/Makefile.in b/lcms2mt/src/Makefile.in index f161d9d64..2ac603483 100644 --- a/lcms2mt/src/Makefile.in +++ b/lcms2mt/src/Makefile.in @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.16.1 from Makefile.am. +# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2018 Free Software Foundation, Inc. +# Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -168,21 +168,7 @@ am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ depcomp = $(SHELL) $(top_srcdir)/depcomp -am__maybe_remake_depfiles = depfiles -am__depfiles_remade = ./$(DEPDIR)/cmsalpha.Plo \ - ./$(DEPDIR)/cmscam02.Plo ./$(DEPDIR)/cmscgats.Plo \ - ./$(DEPDIR)/cmscnvrt.Plo ./$(DEPDIR)/cmserr.Plo \ - ./$(DEPDIR)/cmsgamma.Plo ./$(DEPDIR)/cmsgmt.Plo \ - ./$(DEPDIR)/cmshalf.Plo ./$(DEPDIR)/cmsintrp.Plo \ - ./$(DEPDIR)/cmsio0.Plo ./$(DEPDIR)/cmsio1.Plo \ - ./$(DEPDIR)/cmslut.Plo ./$(DEPDIR)/cmsmd5.Plo \ - ./$(DEPDIR)/cmsmtrx.Plo ./$(DEPDIR)/cmsnamed.Plo \ - ./$(DEPDIR)/cmsopt.Plo ./$(DEPDIR)/cmspack.Plo \ - ./$(DEPDIR)/cmspcs.Plo ./$(DEPDIR)/cmsplugin.Plo \ - ./$(DEPDIR)/cmsps2.Plo ./$(DEPDIR)/cmssamp.Plo \ - ./$(DEPDIR)/cmssm.Plo ./$(DEPDIR)/cmstypes.Plo \ - ./$(DEPDIR)/cmsvirt.Plo ./$(DEPDIR)/cmswtpnt.Plo \ - ./$(DEPDIR)/cmsxform.Plo +am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) @@ -279,6 +265,7 @@ LIBTOOL = @LIBTOOL@ LIBTOOL_DEPS = @LIBTOOL_DEPS@ LIB_JPEG = @LIB_JPEG@ LIB_MATH = @LIB_MATH@ +LIB_PLUGINS = @LIB_PLUGINS@ LIB_THREAD = @LIB_THREAD@ LIB_TIFF = @LIB_TIFF@ LIB_ZLIB = @LIB_ZLIB@ @@ -410,8 +397,8 @@ Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ - echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) @@ -467,38 +454,32 @@ mostlyclean-compile: distclean-compile: -rm -f *.tab.c -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmsalpha.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmscam02.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmscgats.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmscnvrt.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmserr.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmsgamma.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmsgmt.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmshalf.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmsintrp.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmsio0.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmsio1.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmslut.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmsmd5.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmsmtrx.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmsnamed.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmsopt.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmspack.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmspcs.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmsplugin.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmsps2.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmssamp.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmssm.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmstypes.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmsvirt.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmswtpnt.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmsxform.Plo@am__quote@ # am--include-marker - -$(am__depfiles_remade): - @$(MKDIR_P) $(@D) - @echo '# dummy' >$@-t && $(am__mv) $@-t $@ - -am--depfiles: $(am__depfiles_remade) +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmsalpha.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmscam02.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmscgats.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmscnvrt.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmserr.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmsgamma.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmsgmt.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmshalf.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmsintrp.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmsio0.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmsio1.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmslut.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmsmd5.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmsmtrx.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmsnamed.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmsopt.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmspack.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmspcs.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmsplugin.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmsps2.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmssamp.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmssm.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmstypes.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmsvirt.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmswtpnt.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmsxform.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @@ -582,10 +563,7 @@ cscopelist-am: $(am__tagged_files) distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags -distdir: $(BUILT_SOURCES) - $(MAKE) $(AM_MAKEFLAGS) distdir-am - -distdir-am: $(DISTFILES) +distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ @@ -658,32 +636,7 @@ clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \ mostlyclean-am distclean: distclean-am - -rm -f ./$(DEPDIR)/cmsalpha.Plo - -rm -f ./$(DEPDIR)/cmscam02.Plo - -rm -f ./$(DEPDIR)/cmscgats.Plo - -rm -f ./$(DEPDIR)/cmscnvrt.Plo - -rm -f ./$(DEPDIR)/cmserr.Plo - -rm -f ./$(DEPDIR)/cmsgamma.Plo - -rm -f ./$(DEPDIR)/cmsgmt.Plo - -rm -f ./$(DEPDIR)/cmshalf.Plo - -rm -f ./$(DEPDIR)/cmsintrp.Plo - -rm -f ./$(DEPDIR)/cmsio0.Plo - -rm -f ./$(DEPDIR)/cmsio1.Plo - -rm -f ./$(DEPDIR)/cmslut.Plo - -rm -f ./$(DEPDIR)/cmsmd5.Plo - -rm -f ./$(DEPDIR)/cmsmtrx.Plo - -rm -f ./$(DEPDIR)/cmsnamed.Plo - -rm -f ./$(DEPDIR)/cmsopt.Plo - -rm -f ./$(DEPDIR)/cmspack.Plo - -rm -f ./$(DEPDIR)/cmspcs.Plo - -rm -f ./$(DEPDIR)/cmsplugin.Plo - -rm -f ./$(DEPDIR)/cmsps2.Plo - -rm -f ./$(DEPDIR)/cmssamp.Plo - -rm -f ./$(DEPDIR)/cmssm.Plo - -rm -f ./$(DEPDIR)/cmstypes.Plo - -rm -f ./$(DEPDIR)/cmsvirt.Plo - -rm -f ./$(DEPDIR)/cmswtpnt.Plo - -rm -f ./$(DEPDIR)/cmsxform.Plo + -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags @@ -729,32 +682,7 @@ install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am - -rm -f ./$(DEPDIR)/cmsalpha.Plo - -rm -f ./$(DEPDIR)/cmscam02.Plo - -rm -f ./$(DEPDIR)/cmscgats.Plo - -rm -f ./$(DEPDIR)/cmscnvrt.Plo - -rm -f ./$(DEPDIR)/cmserr.Plo - -rm -f ./$(DEPDIR)/cmsgamma.Plo - -rm -f ./$(DEPDIR)/cmsgmt.Plo - -rm -f ./$(DEPDIR)/cmshalf.Plo - -rm -f ./$(DEPDIR)/cmsintrp.Plo - -rm -f ./$(DEPDIR)/cmsio0.Plo - -rm -f ./$(DEPDIR)/cmsio1.Plo - -rm -f ./$(DEPDIR)/cmslut.Plo - -rm -f ./$(DEPDIR)/cmsmd5.Plo - -rm -f ./$(DEPDIR)/cmsmtrx.Plo - -rm -f ./$(DEPDIR)/cmsnamed.Plo - -rm -f ./$(DEPDIR)/cmsopt.Plo - -rm -f ./$(DEPDIR)/cmspack.Plo - -rm -f ./$(DEPDIR)/cmspcs.Plo - -rm -f ./$(DEPDIR)/cmsplugin.Plo - -rm -f ./$(DEPDIR)/cmsps2.Plo - -rm -f ./$(DEPDIR)/cmssamp.Plo - -rm -f ./$(DEPDIR)/cmssm.Plo - -rm -f ./$(DEPDIR)/cmstypes.Plo - -rm -f ./$(DEPDIR)/cmsvirt.Plo - -rm -f ./$(DEPDIR)/cmswtpnt.Plo - -rm -f ./$(DEPDIR)/cmsxform.Plo + -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic @@ -775,9 +703,9 @@ uninstall-am: uninstall-libLTLIBRARIES .MAKE: install-am install-strip -.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ - clean-generic clean-libLTLIBRARIES clean-libtool cscopelist-am \ - ctags ctags-am distclean distclean-compile distclean-generic \ +.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ + clean-libLTLIBRARIES clean-libtool cscopelist-am ctags \ + ctags-am distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ diff --git a/lcms2mt/src/cmsalpha.c b/lcms2mt/src/cmsalpha.c index 697161ccb..c192d927a 100644 --- a/lcms2mt/src/cmsalpha.c +++ b/lcms2mt/src/cmsalpha.c @@ -75,7 +75,7 @@ static void from8to16(void* dst, const void* src) { cmsUInt8Number n = *(cmsUInt8Number*)src; - *(cmsUInt16Number*) dst = FROM_8_TO_16(n); + *(cmsUInt16Number*) dst = (cmsUInt16Number) FROM_8_TO_16(n); } static @@ -88,13 +88,13 @@ void from8to16SE(void* dst, const void* src) static void from8toFLT(void* dst, const void* src) { - *(cmsFloat32Number*)dst = (*(cmsUInt8Number*)src) / 255.0f; + *(cmsFloat32Number*)dst = (cmsFloat32Number) (*(cmsUInt8Number*)src) / 255.0f; } static void from8toDBL(void* dst, const void* src) { - *(cmsFloat64Number*)dst = (*(cmsUInt8Number*)src) / 255.0; + *(cmsFloat64Number*)dst = (cmsFloat64Number) (*(cmsUInt8Number*)src) / 255.0; } static @@ -153,13 +153,13 @@ void from16SEtoFLT(void* dst, const void* src) static void from16toDBL(void* dst, const void* src) { - *(cmsFloat64Number*)dst = (*(cmsUInt16Number*)src) / 65535.0f; + *(cmsFloat64Number*)dst = (cmsFloat64Number) (*(cmsUInt16Number*)src) / 65535.0; } static void from16SEtoDBL(void* dst, const void* src) { - *(cmsFloat64Number*)dst = (CHANGE_ENDIAN(*(cmsUInt16Number*)src)) / 65535.0f; + *(cmsFloat64Number*)dst = (cmsFloat64Number) (CHANGE_ENDIAN(*(cmsUInt16Number*)src)) / 65535.0; } static @@ -275,6 +275,7 @@ void fromHLFto16SE(void* dst, const void* src) cmsUNUSED_PARAMETER(src); #endif } + static void fromHLFtoFLT(void* dst, const void* src) { @@ -319,6 +320,7 @@ void fromDBLto16SE(void* dst, const void* src) cmsUInt16Number i = _cmsQuickSaturateWord(n * 65535.0f); *(cmsUInt16Number*)dst = CHANGE_ENDIAN(i); } + static void fromDBLtoFLT(void* dst, const void* src) { @@ -359,11 +361,12 @@ int FormatterPos(cmsUInt32Number frm) #endif if (b == 4 && T_FLOAT(frm)) return 4; // FLT - if (b == 2 && !T_FLOAT(frm)) { - if (T_ENDIAN16(frm)) - return 2; // 16SE - else - return 1; // 16 + if (b == 2 && !T_FLOAT(frm)) + { + if (T_ENDIAN16(frm)) + return 2; // 16SE + else + return 1; // 16 } if (b == 1 && !T_FLOAT(frm)) return 0; // 8 @@ -386,7 +389,7 @@ static cmsFormatterAlphaFn FormattersAlpha[6][6] = { int in_n = FormatterPos(in); int out_n = FormatterPos(out); - if (in_n < 0 || out_n < 0 || in_n > 4 || out_n > 4) { + if (in_n < 0 || out_n < 0 || in_n > 5 || out_n > 5) { cmsSignalError(id, cmsERROR_UNKNOWN_EXTENSION, "Unrecognized alpha channel width"); return NULL; @@ -568,6 +571,8 @@ void _cmsHandleExtraChannels(cmsContext ContextID, _cmsTRANSFORM* p, const void* // Check for conversions 8, 16, half, float, dbl copyValueFn = _cmsGetFormatterAlpha(ContextID, p->InputFormat, p->OutputFormat); + if (copyValueFn == NULL) + return; if (nExtra == 1) { // Optimized routine for copying a single extra channel quickly diff --git a/lcms2mt/src/cmscgats.c b/lcms2mt/src/cmscgats.c index 3657177da..dcad06a0b 100644 --- a/lcms2mt/src/cmscgats.c +++ b/lcms2mt/src/cmscgats.c @@ -1495,6 +1495,14 @@ cmsBool CMSEXPORT cmsIT8SetDataFormat(cmsContext ContextID, cmsHANDLE h, int n, return SetDataFormat(ContextID, it8, n, Sample); } +// A safe atoi that returns 0 when NULL input is given +static +cmsInt32Number satoi(const char* b) +{ + if (b == NULL) return 0; + return atoi(b); +} + static void AllocateDataSet(cmsContext ContextID, cmsIT8* it8) { @@ -1502,14 +1510,15 @@ void AllocateDataSet(cmsContext ContextID, cmsIT8* it8) if (t -> Data) return; // Already allocated - t-> nSamples = atoi(cmsIT8GetProperty(ContextID, it8, "NUMBER_OF_FIELDS")); - t-> nPatches = atoi(cmsIT8GetProperty(ContextID, it8, "NUMBER_OF_SETS")); + t-> nSamples = satoi(cmsIT8GetProperty(ContextID, it8, "NUMBER_OF_FIELDS")); + t-> nPatches = satoi(cmsIT8GetProperty(ContextID, it8, "NUMBER_OF_SETS")); if (t -> nSamples < 0 || t->nSamples > 0x7ffe || t->nPatches < 0 || t->nPatches > 0x7ffe) { SynError(ContextID, it8, "AllocateDataSet: too much data"); } else { + // Some dumb analizers warns of possible overflow here, just take a look couple of lines above. t->Data = (char**)AllocChunk(ContextID, it8, ((cmsUInt32Number)t->nSamples + 1) * ((cmsUInt32Number)t->nPatches + 1) * sizeof(char*)); if (t->Data == NULL) { @@ -1676,11 +1685,11 @@ void WriteHeader(cmsContext ContextID, cmsIT8* it8, SAVESTREAM* fp) break; case WRITE_HEXADECIMAL: - Writef(ContextID, fp, "\t0x%X", atoi(p ->Value)); + Writef(ContextID, fp, "\t0x%X", satoi(p ->Value)); break; case WRITE_BINARY: - Writef(ContextID, fp, "\t0x%B", atoi(p ->Value)); + Writef(ContextID, fp, "\t0x%B", satoi(p ->Value)); break; case WRITE_PAIR: @@ -1709,7 +1718,7 @@ void WriteDataFormat(cmsContext ContextID, SAVESTREAM* fp, cmsIT8* it8) WriteStr(ContextID, fp, "BEGIN_DATA_FORMAT\n"); WriteStr(ContextID, fp, " "); - nSamples = atoi(cmsIT8GetProperty(ContextID, it8, "NUMBER_OF_FIELDS")); + nSamples = satoi(cmsIT8GetProperty(ContextID, it8, "NUMBER_OF_FIELDS")); for (i = 0; i < nSamples; i++) { @@ -1732,7 +1741,7 @@ void WriteData(cmsContext ContextID, SAVESTREAM* fp, cmsIT8* it8) WriteStr (ContextID, fp, "BEGIN_DATA\n"); - t->nPatches = atoi(cmsIT8GetProperty(ContextID, it8, "NUMBER_OF_SETS")); + t->nPatches = satoi(cmsIT8GetProperty(ContextID, it8, "NUMBER_OF_SETS")); for (i = 0; i < t-> nPatches; i++) { diff --git a/lcms2mt/src/cmscnvrt.c b/lcms2mt/src/cmscnvrt.c index e3a2ddbc1..642636967 100644 --- a/lcms2mt/src/cmscnvrt.c +++ b/lcms2mt/src/cmscnvrt.c @@ -731,6 +731,9 @@ cmsPipeline* BlackPreservingKOnlyIntents(cmsContext ContextID, cmsUInt32Number ICCIntents[256]; cmsStage* CLUT; cmsUInt32Number i, nGridPoints; + cmsUInt32Number lastProfilePos; + cmsUInt32Number preservationProfilesCount; + cmsHPROFILE hLastProfile; // Sanity check @@ -740,20 +743,36 @@ cmsPipeline* BlackPreservingKOnlyIntents(cmsContext ContextID, for (i=0; i < nProfiles; i++) ICCIntents[i] = TranslateNonICCIntents(TheIntents[i]); + + // Trim all CMYK devicelinks at the end + lastProfilePos = nProfiles - 1; + hLastProfile = hProfiles[lastProfilePos]; + + while (lastProfilePos > 1) + { + hLastProfile = hProfiles[--lastProfilePos]; + if (cmsGetColorSpace(ContextID, hLastProfile) != cmsSigCmykData || + cmsGetDeviceClass(ContextID, hLastProfile) != cmsSigLinkClass) + break; + } + + preservationProfilesCount = lastProfilePos + 1; + // Check for non-cmyk profiles if (cmsGetColorSpace(ContextID, hProfiles[0]) != cmsSigCmykData || - cmsGetColorSpace(ContextID, hProfiles[nProfiles-1]) != cmsSigCmykData) + !(cmsGetColorSpace(ContextID, hLastProfile) == cmsSigCmykData || + cmsGetDeviceClass(ContextID, hLastProfile) == cmsSigOutputClass)) return DefaultICCintents(ContextID, nProfiles, ICCIntents, hProfiles, BPC, AdaptationStates, dwFlags); - memset(&bp, 0, sizeof(bp)); - // Allocate an empty LUT for holding the result Result = cmsPipelineAlloc(ContextID, 4, 4); if (Result == NULL) return NULL; + memset(&bp, 0, sizeof(bp)); + // Create a LUT holding normal ICC transform bp.cmyk2cmyk = DefaultICCintents(ContextID, - nProfiles, + preservationProfilesCount, ICCIntents, hProfiles, BPC, @@ -765,7 +784,7 @@ cmsPipeline* BlackPreservingKOnlyIntents(cmsContext ContextID, // Now, compute the tone curve bp.KTone = _cmsBuildKToneCurve(ContextID, 4096, - nProfiles, + preservationProfilesCount, ICCIntents, hProfiles, BPC, @@ -790,6 +809,19 @@ cmsPipeline* BlackPreservingKOnlyIntents(cmsContext ContextID, if (!cmsStageSampleCLut16bit(ContextID, CLUT, BlackPreservingGrayOnlySampler, (void*) &bp, 0)) goto Error; + + // Insert possible devicelinks at the end + for (i = lastProfilePos + 1; i < nProfiles; i++) + { + cmsPipeline* devlink = _cmsReadDevicelinkLUT(ContextID, hProfiles[i], ICCIntents[i]); + if (devlink == NULL) + goto Error; + + if (!cmsPipelineCat(ContextID, Result, devlink)) + goto Error; + } + + // Get rid of xform and tone curve cmsPipelineFree(ContextID, bp.cmyk2cmyk); cmsFreeToneCurve(ContextID, bp.KTone); @@ -908,6 +940,8 @@ int BlackPreservingSampler(cmsContext ContextID, CMSREGISTER const cmsUInt16Numb return TRUE; } + + // This is the entry for black-plane preserving, which are non-ICC static cmsPipeline* BlackPreservingKPlaneIntents(cmsContext ContextID, @@ -919,10 +953,14 @@ cmsPipeline* BlackPreservingKPlaneIntents(cmsContext ContextID, cmsUInt32Number dwFlags) { PreserveKPlaneParams bp; + cmsPipeline* Result = NULL; cmsUInt32Number ICCIntents[256]; cmsStage* CLUT; cmsUInt32Number i, nGridPoints; + cmsUInt32Number lastProfilePos; + cmsUInt32Number preservationProfilesCount; + cmsHPROFILE hLastProfile; cmsHPROFILE hLab; // Sanity check @@ -932,32 +970,45 @@ cmsPipeline* BlackPreservingKPlaneIntents(cmsContext ContextID, for (i=0; i < nProfiles; i++) ICCIntents[i] = TranslateNonICCIntents(TheIntents[i]); + // Trim all CMYK devicelinks at the end + lastProfilePos = nProfiles - 1; + hLastProfile = hProfiles[lastProfilePos]; + + while (lastProfilePos > 1) + { + hLastProfile = hProfiles[--lastProfilePos]; + if (cmsGetColorSpace(ContextID, hLastProfile) != cmsSigCmykData || + cmsGetDeviceClass(ContextID, hLastProfile) != cmsSigLinkClass) + break; + } + + preservationProfilesCount = lastProfilePos + 1; + // Check for non-cmyk profiles if (cmsGetColorSpace(ContextID, hProfiles[0]) != cmsSigCmykData || - !(cmsGetColorSpace(ContextID, hProfiles[nProfiles-1]) == cmsSigCmykData || - cmsGetDeviceClass(ContextID, hProfiles[nProfiles-1]) == cmsSigOutputClass)) + !(cmsGetColorSpace(ContextID, hLastProfile) == cmsSigCmykData || + cmsGetDeviceClass(ContextID, hLastProfile) == cmsSigOutputClass)) return DefaultICCintents(ContextID, nProfiles, ICCIntents, hProfiles, BPC, AdaptationStates, dwFlags); // Allocate an empty LUT for holding the result Result = cmsPipelineAlloc(ContextID, 4, 4); if (Result == NULL) return NULL; - memset(&bp, 0, sizeof(bp)); // We need the input LUT of the last profile, assuming this one is responsible of // black generation. This LUT will be searched in inverse order. - bp.LabK2cmyk = _cmsReadInputLUT(ContextID, hProfiles[nProfiles-1], INTENT_RELATIVE_COLORIMETRIC); + bp.LabK2cmyk = _cmsReadInputLUT(ContextID, hLastProfile, INTENT_RELATIVE_COLORIMETRIC); if (bp.LabK2cmyk == NULL) goto Cleanup; // Get total area coverage (in 0..1 domain) - bp.MaxTAC = cmsDetectTAC(ContextID, hProfiles[nProfiles-1]) / 100.0; + bp.MaxTAC = cmsDetectTAC(ContextID, hLastProfile) / 100.0; if (bp.MaxTAC <= 0) goto Cleanup; // Create a LUT holding normal ICC transform bp.cmyk2cmyk = DefaultICCintents(ContextID, - nProfiles, + preservationProfilesCount, ICCIntents, hProfiles, BPC, @@ -966,7 +1017,7 @@ cmsPipeline* BlackPreservingKPlaneIntents(cmsContext ContextID, if (bp.cmyk2cmyk == NULL) goto Cleanup; // Now the tone curve - bp.KTone = _cmsBuildKToneCurve(ContextID, 4096, nProfiles, + bp.KTone = _cmsBuildKToneCurve(ContextID, 4096, preservationProfilesCount, ICCIntents, hProfiles, BPC, @@ -976,14 +1027,14 @@ cmsPipeline* BlackPreservingKPlaneIntents(cmsContext ContextID, // To measure the output, Last profile to Lab hLab = cmsCreateLab4Profile(ContextID, NULL); - bp.hProofOutput = cmsCreateTransform(ContextID, hProfiles[nProfiles-1], + bp.hProofOutput = cmsCreateTransform(ContextID, hLastProfile, CHANNELS_SH(4)|BYTES_SH(2), hLab, TYPE_Lab_DBL, INTENT_RELATIVE_COLORIMETRIC, cmsFLAGS_NOCACHE|cmsFLAGS_NOOPTIMIZE); if ( bp.hProofOutput == NULL) goto Cleanup; // Same as anterior, but lab in the 0..1 range - bp.cmyk2Lab = cmsCreateTransform(ContextID, hProfiles[nProfiles-1], + bp.cmyk2Lab = cmsCreateTransform(ContextID, hLastProfile, FLOAT_SH(1)|CHANNELS_SH(4)|BYTES_SH(4), hLab, FLOAT_SH(1)|CHANNELS_SH(3)|BYTES_SH(4), INTENT_RELATIVE_COLORIMETRIC, @@ -1006,6 +1057,18 @@ cmsPipeline* BlackPreservingKPlaneIntents(cmsContext ContextID, cmsStageSampleCLut16bit(ContextID, CLUT, BlackPreservingSampler, (void*) &bp, 0); + // Insert possible devicelinks at the end + for (i = lastProfilePos + 1; i < nProfiles; i++) + { + cmsPipeline* devlink = _cmsReadDevicelinkLUT(ContextID, hProfiles[i], ICCIntents[i]); + if (devlink == NULL) + goto Cleanup; + + if (!cmsPipelineCat(ContextID, Result, devlink)) + goto Cleanup; + } + + Cleanup: if (bp.cmyk2cmyk) cmsPipelineFree(ContextID, bp.cmyk2cmyk); @@ -1018,6 +1081,8 @@ Cleanup: return Result; } + + // Link routines ------------------------------------------------------------------------------------------------------ // Chain several profiles into a single LUT. It just checks the parameters and then calls the handler diff --git a/lcms2mt/src/cmsgamma.c b/lcms2mt/src/cmsgamma.c index ad00b1292..6edbc841e 100644 --- a/lcms2mt/src/cmsgamma.c +++ b/lcms2mt/src/cmsgamma.c @@ -59,11 +59,11 @@ static cmsFloat64Number DefaultEvalParametricFn(cmsContext ContextID, cmsInt32Nu // The built-in list static _cmsParametricCurvesCollection DefaultCurves = { - 9, // # of curve types - { 1, 2, 3, 4, 5, 6, 7, 8, 108 }, // Parametric curve ID - { 1, 3, 4, 5, 7, 4, 5, 5, 1 }, // Parameters by type - DefaultEvalParametricFn, // Evaluator - NULL // Next in chain + 10, // # of curve types + { 1, 2, 3, 4, 5, 6, 7, 8, 108, 109 }, // Parametric curve ID + { 1, 3, 4, 5, 7, 4, 5, 5, 1, 1 }, // Parameters by type + DefaultEvalParametricFn, // Evaluator + NULL // Next in chain }; // Duplicates the zone of memory used by the plug-in in the new context @@ -300,8 +300,8 @@ cmsToneCurve* AllocateToneCurveStruct(cmsContext ContextID, cmsUInt32Number nEnt return p; Error: - if (p->SegInterp) _cmsFree(ContextID, p->SegInterp); - if (p -> Segments) _cmsFree(ContextID, p ->Segments); + if (p -> SegInterp) _cmsFree(ContextID, p -> SegInterp); + if (p -> Segments) _cmsFree(ContextID, p -> Segments); if (p -> Evals) _cmsFree(ContextID, p -> Evals); if (p ->Table16) _cmsFree(ContextID, p ->Table16); _cmsFree(ContextID, p); @@ -309,6 +309,32 @@ Error: } +// Generates a sigmoidal function with desired steepness. +cmsINLINE double sigmoid_base(double k, double t) +{ + return (1.0 / (1.0 + exp(-k * t))) - 0.5; +} + +cmsINLINE double inverted_sigmoid_base(double k, double t) +{ + return -log((1.0 / (t + 0.5)) - 1.0) / k; +} + +cmsINLINE double sigmoid_factory(double k, double t) +{ + double correction = 0.5 / sigmoid_base(k, 1); + + return correction * sigmoid_base(k, 2.0 * t - 1.0) + 0.5; +} + +cmsINLINE double inverse_sigmoid_factory(double k, double t) +{ + double correction = 0.5 / sigmoid_base(k, 1); + + return (inverted_sigmoid_base(k, (t - 0.5) / correction) + 1.0) / 2.0; +} + + // Parametric Fn using floating point static cmsFloat64Number DefaultEvalParametricFn(cmsContext ContextID, cmsInt32Number Type, const cmsFloat64Number Params[], cmsFloat64Number R) @@ -641,6 +667,7 @@ cmsFloat64Number DefaultEvalParametricFn(cmsContext ContextID, cmsInt32Number Ty } break; + // S-Shaped: (1 - (1-x)^1/g)^1/g case 108: if (fabs(Params[0]) < MATRIX_DET_TOLERANCE) @@ -658,6 +685,15 @@ cmsFloat64Number DefaultEvalParametricFn(cmsContext ContextID, cmsInt32Number Ty Val = 1 - pow(1 - pow(R, Params[0]), Params[0]); break; + // Sigmoidals + case 109: + Val = sigmoid_factory(Params[0], R); + break; + + case -109: + Val = inverse_sigmoid_factory(Params[0], R); + break; + default: // Unsupported parametric curve. Should never reach here return 0; @@ -941,7 +977,7 @@ cmsToneCurve* CMSEXPORT cmsJoinToneCurve(cmsContext ContextID, //Iterate for (i=0; i < nResultingPoints; i++) { - t = (cmsFloat32Number) i / (nResultingPoints-1); + t = (cmsFloat32Number) i / (cmsFloat32Number)(nResultingPoints-1); x = cmsEvalToneCurveFloat(ContextID, X, t); Res[i] = cmsEvalToneCurveFloat(ContextID, Yreversed, x); } @@ -1155,6 +1191,7 @@ cmsBool CMSEXPORT cmsSmoothToneCurve(cmsContext ContextID, cmsToneCurve* Tab, c cmsBool SuccessStatus = TRUE; cmsFloat32Number *w, *y, *z; cmsUInt32Number i, nItems, Zeros, Poles; + cmsBool notCheck = FALSE; if (Tab != NULL && Tab->InterpParams != NULL) { @@ -1180,6 +1217,12 @@ cmsBool CMSEXPORT cmsSmoothToneCurve(cmsContext ContextID, cmsToneCurve* Tab, c w[i + 1] = 1.0; } + if (lambda < 0) + { + notCheck = TRUE; + lambda = -lambda; + } + if (smooth2(ContextID, w, y, z, (cmsFloat32Number)lambda, (int)nItems)) { // Do some reality - checking... @@ -1192,7 +1235,7 @@ cmsBool CMSEXPORT cmsSmoothToneCurve(cmsContext ContextID, cmsToneCurve* Tab, c if (z[i] < z[i - 1]) { cmsSignalError(ContextID, cmsERROR_RANGE, "cmsSmoothToneCurve: Non-Monotonic."); - SuccessStatus = FALSE; + SuccessStatus = notCheck; break; } } @@ -1200,13 +1243,13 @@ cmsBool CMSEXPORT cmsSmoothToneCurve(cmsContext ContextID, cmsToneCurve* Tab, c if (SuccessStatus && Zeros > (nItems / 3)) { cmsSignalError(ContextID, cmsERROR_RANGE, "cmsSmoothToneCurve: Degenerated, mostly zeros."); - SuccessStatus = FALSE; + SuccessStatus = notCheck; } if (SuccessStatus && Poles > (nItems / 3)) { cmsSignalError(ContextID, cmsERROR_RANGE, "cmsSmoothToneCurve: Degenerated, mostly poles."); - SuccessStatus = FALSE; + SuccessStatus = notCheck; } if (SuccessStatus) // Seems ok @@ -1433,3 +1476,14 @@ cmsFloat64Number CMSEXPORT cmsEstimateGamma(cmsContext ContextID, const cmsToneC return (sum / n); // The mean } + + +// Retrieve parameters on one-segment tone curves + +cmsFloat64Number* CMSEXPORT cmsGetToneCurveParams(cmsContext contextID, const cmsToneCurve* t) +{ + _cmsAssert(t != NULL); + + if (t->nSegments != 1) return NULL; + return t->Segments[0].Params; +} diff --git a/lcms2mt/src/cmsintrp.c b/lcms2mt/src/cmsintrp.c index 590328aa9..a8854113d 100644 --- a/lcms2mt/src/cmsintrp.c +++ b/lcms2mt/src/cmsintrp.c @@ -412,12 +412,13 @@ void BilinearInterp16(cmsContext ContextID, const cmsUInt16Number* LutTable = (cmsUInt16Number*) p ->Table; int OutChan, TotalOut; cmsS15Fixed16Number fx, fy; - CMSREGISTER int rx, ry; - int x0, y0; - CMSREGISTER int X0, X1, Y0, Y1; - int d00, d01, d10, d11, - dx0, dx1, - dxy; + CMSREGISTER int rx, ry; + int x0, y0; + CMSREGISTER int X0, X1, Y0, Y1; + + int d00, d01, d10, d11, + dx0, dx1, + dxy; cmsUNUSED_PARAMETER(ContextID); TotalOut = p -> nOutputs; @@ -474,11 +475,12 @@ void TrilinearInterpFloat(cmsContext ContextID, const cmsFloat32Number Input[], int x0, y0, z0, X0, Y0, Z0, X1, Y1, Z1; int TotalOut, OutChan; + cmsFloat32Number fx, fy, fz, - d000, d001, d010, d011, - d100, d101, d110, d111, - dx00, dx01, dx10, dx11, - dxy0, dxy1, dxyz; + d000, d001, d010, d011, + d100, d101, d110, d111, + dx00, dx01, dx10, dx11, + dxy0, dxy1, dxyz; cmsUNUSED_PARAMETER(ContextID); TotalOut = p -> nOutputs; @@ -546,13 +548,13 @@ void TrilinearInterp16(cmsContext ContextID, const cmsUInt16Number* LutTable = (cmsUInt16Number*) p ->Table; int OutChan, TotalOut; cmsS15Fixed16Number fx, fy, fz; - CMSREGISTER int rx, ry, rz; - int x0, y0, z0; - CMSREGISTER int X0, X1, Y0, Y1, Z0, Z1; - int d000, d001, d010, d011, - d100, d101, d110, d111, - dx00, dx01, dx10, dx11, - dxy0, dxy1, dxyz; + CMSREGISTER int rx, ry, rz; + int x0, y0, z0; + CMSREGISTER int X0, X1, Y0, Y1, Z0, Z1; + int d000, d001, d010, d011, + d100, d101, d110, d111, + dx00, dx01, dx10, dx11, + dxy0, dxy1, dxyz; cmsUNUSED_PARAMETER(ContextID); TotalOut = p -> nOutputs; @@ -621,8 +623,8 @@ void TetrahedralInterpFloat(cmsContext ContextID, const cmsFloat32Number Input[] { const cmsFloat32Number* LutTable = (cmsFloat32Number*) p -> Table; cmsFloat32Number px, py, pz; - int x0, y0, z0, - X0, Y0, Z0, X1, Y1, Z1; + int x0, y0, z0, + X0, Y0, Z0, X1, Y1, Z1; cmsFloat32Number rx, ry, rz; cmsFloat32Number c0, c1=0, c2=0, c3=0; int OutChan, TotalOut; @@ -713,9 +715,6 @@ void TetrahedralInterpFloat(cmsContext ContextID, const cmsFloat32Number Input[] #undef DENS - - - static CMS_NO_SANITIZE void TetrahedralInterp16(cmsContext ContextID, CMSREGISTER const cmsUInt16Number Input[], @@ -727,7 +726,7 @@ void TetrahedralInterp16(cmsContext ContextID, cmsS15Fixed16Number rx, ry, rz; int x0, y0, z0; cmsS15Fixed16Number c0, c1, c2, c3, Rest; - cmsS15Fixed16Number X0, X1, Y0, Y1, Z0, Z1; + cmsUInt32Number X0, X1, Y0, Y1, Z0, Z1; cmsUInt32Number TotalOut = p -> nOutputs; cmsUNUSED_PARAMETER(ContextID); @@ -752,7 +751,7 @@ void TetrahedralInterp16(cmsContext ContextID, Z0 = p -> opta[0] * z0; Z1 = (Input[2] == 0xFFFFU ? 0 : p->opta[0]); - LutTable = &LutTable[X0+Y0+Z0]; + LutTable += X0+Y0+Z0; // Output should be computed as x = ROUND_FIXED_TO_INT(_cmsToFixedDomain(Rest)) // which expands as: x = (Rest + ((Rest+0x7fff)/0xFFFF) + 0x8000)>>16 @@ -1038,8 +1037,6 @@ void Eval4Inputs(cmsContext ContextID, // For more that 3 inputs (i.e., CMYK) // evaluate two 3-dimensional interpolations and then linearly interpolate between them. - - static void Eval4InputsFloat(cmsContext ContextID, const cmsFloat32Number Input[], cmsFloat32Number Output[], @@ -1082,354 +1079,102 @@ void Eval4InputsFloat(cmsContext ContextID, const cmsFloat32Number Input[], } } - -static CMS_NO_SANITIZE -void Eval5Inputs(cmsContext ContextID, - CMSREGISTER const cmsUInt16Number Input[], - CMSREGISTER cmsUInt16Number Output[], - CMSREGISTER const cmsInterpParams* p16) -{ - const cmsUInt16Number* LutTable = (cmsUInt16Number*) p16 -> Table; - cmsS15Fixed16Number fk; - cmsS15Fixed16Number k0, rk; - int K0, K1; - const cmsUInt16Number* T; - cmsUInt32Number i; - cmsUInt16Number Tmp1[MAX_STAGE_CHANNELS], Tmp2[MAX_STAGE_CHANNELS]; - cmsInterpParams p1; - - - fk = _cmsToFixedDomain((cmsS15Fixed16Number) Input[0] * p16 -> Domain[0]); - k0 = FIXED_TO_INT(fk); - rk = FIXED_REST_TO_INT(fk); - - K0 = p16 -> opta[4] * k0; - K1 = p16 -> opta[4] * (k0 + (Input[0] != 0xFFFFU ? 1 : 0)); - - p1 = *p16; - memmove(&p1.Domain[0], &p16 ->Domain[1], 4*sizeof(cmsUInt32Number)); - - T = LutTable + K0; - p1.Table = T; - - Eval4Inputs(ContextID, Input + 1, Tmp1, &p1); - - T = LutTable + K1; - p1.Table = T; - - Eval4Inputs(ContextID, Input + 1, Tmp2, &p1); - - for (i=0; i < p16 -> nOutputs; i++) { - - Output[i] = LinearInterp(rk, Tmp1[i], Tmp2[i]); - } - -} - - -static -void Eval5InputsFloat(cmsContext ContextID, const cmsFloat32Number Input[], - cmsFloat32Number Output[], - const cmsInterpParams* p) -{ - const cmsFloat32Number* LutTable = (cmsFloat32Number*) p -> Table; - cmsFloat32Number rest; - cmsFloat32Number pk; - int k0, K0, K1; - const cmsFloat32Number* T; - cmsUInt32Number i; - cmsFloat32Number Tmp1[MAX_STAGE_CHANNELS], Tmp2[MAX_STAGE_CHANNELS]; - cmsInterpParams p1; - - pk = fclamp(Input[0]) * p->Domain[0]; - k0 = _cmsQuickFloor(pk); - rest = pk - (cmsFloat32Number) k0; - - K0 = p -> opta[4] * k0; - K1 = K0 + (fclamp(Input[0]) >= 1.0 ? 0 : p->opta[4]); - - p1 = *p; - memmove(&p1.Domain[0], &p ->Domain[1], 4*sizeof(cmsUInt32Number)); - - T = LutTable + K0; - p1.Table = T; - - Eval4InputsFloat(ContextID, Input + 1, Tmp1, &p1); - - T = LutTable + K1; - p1.Table = T; - - Eval4InputsFloat(ContextID, Input + 1, Tmp2, &p1); - - for (i=0; i < p -> nOutputs; i++) { - - cmsFloat32Number y0 = Tmp1[i]; - cmsFloat32Number y1 = Tmp2[i]; - - Output[i] = y0 + (y1 - y0) * rest; - } -} - - - -static CMS_NO_SANITIZE -void Eval6Inputs(cmsContext ContextID, - CMSREGISTER const cmsUInt16Number Input[], - CMSREGISTER cmsUInt16Number Output[], - CMSREGISTER const cmsInterpParams* p16) -{ - const cmsUInt16Number* LutTable = (cmsUInt16Number*) p16 -> Table; - cmsS15Fixed16Number fk; - cmsS15Fixed16Number k0, rk; - int K0, K1; - const cmsUInt16Number* T; - cmsUInt32Number i; - cmsUInt16Number Tmp1[MAX_STAGE_CHANNELS], Tmp2[MAX_STAGE_CHANNELS]; - cmsInterpParams p1; - - fk = _cmsToFixedDomain((cmsS15Fixed16Number) Input[0] * p16 -> Domain[0]); - k0 = FIXED_TO_INT(fk); - rk = FIXED_REST_TO_INT(fk); - - K0 = p16 -> opta[5] * k0; - K1 = p16 -> opta[5] * (k0 + (Input[0] != 0xFFFFU ? 1 : 0)); - - p1 = *p16; - memmove(&p1.Domain[0], &p16 ->Domain[1], 5*sizeof(cmsUInt32Number)); - - T = LutTable + K0; - p1.Table = T; - - Eval5Inputs(ContextID, Input + 1, Tmp1, &p1); - - T = LutTable + K1; - p1.Table = T; - - Eval5Inputs(ContextID, Input + 1, Tmp2, &p1); - - for (i=0; i < p16 -> nOutputs; i++) { - - Output[i] = LinearInterp(rk, Tmp1[i], Tmp2[i]); - } - -} - - -static -void Eval6InputsFloat(cmsContext ContextID, const cmsFloat32Number Input[], - cmsFloat32Number Output[], - const cmsInterpParams* p) -{ - const cmsFloat32Number* LutTable = (cmsFloat32Number*) p -> Table; - cmsFloat32Number rest; - cmsFloat32Number pk; - int k0, K0, K1; - const cmsFloat32Number* T; - cmsUInt32Number i; - cmsFloat32Number Tmp1[MAX_STAGE_CHANNELS], Tmp2[MAX_STAGE_CHANNELS]; - cmsInterpParams p1; - - pk = fclamp(Input[0]) * p->Domain[0]; - k0 = _cmsQuickFloor(pk); - rest = pk - (cmsFloat32Number) k0; - - K0 = p -> opta[5] * k0; - K1 = K0 + (fclamp(Input[0]) >= 1.0 ? 0 : p->opta[5]); - - p1 = *p; - memmove(&p1.Domain[0], &p ->Domain[1], 5*sizeof(cmsUInt32Number)); - - T = LutTable + K0; - p1.Table = T; - - Eval5InputsFloat(ContextID, Input + 1, Tmp1, &p1); - - T = LutTable + K1; - p1.Table = T; - - Eval5InputsFloat(ContextID, Input + 1, Tmp2, &p1); - - for (i=0; i < p -> nOutputs; i++) { - - cmsFloat32Number y0 = Tmp1[i]; - cmsFloat32Number y1 = Tmp2[i]; - - Output[i] = y0 + (y1 - y0) * rest; - } -} - - -static CMS_NO_SANITIZE -void Eval7Inputs(cmsContext ContextID, - CMSREGISTER const cmsUInt16Number Input[], - CMSREGISTER cmsUInt16Number Output[], - CMSREGISTER const cmsInterpParams* p16) -{ - const cmsUInt16Number* LutTable = (cmsUInt16Number*) p16 -> Table; - cmsS15Fixed16Number fk; - cmsS15Fixed16Number k0, rk; - int K0, K1; - const cmsUInt16Number* T; - cmsUInt32Number i; - cmsUInt16Number Tmp1[MAX_STAGE_CHANNELS], Tmp2[MAX_STAGE_CHANNELS]; - cmsInterpParams p1; - - - fk = _cmsToFixedDomain((cmsS15Fixed16Number) Input[0] * p16 -> Domain[0]); - k0 = FIXED_TO_INT(fk); - rk = FIXED_REST_TO_INT(fk); - - K0 = p16 -> opta[6] * k0; - K1 = p16 -> opta[6] * (k0 + (Input[0] != 0xFFFFU ? 1 : 0)); - - p1 = *p16; - memmove(&p1.Domain[0], &p16 ->Domain[1], 6*sizeof(cmsUInt32Number)); - - T = LutTable + K0; - p1.Table = T; - - Eval6Inputs(ContextID, Input + 1, Tmp1, &p1); - - T = LutTable + K1; - p1.Table = T; - - Eval6Inputs(ContextID, Input + 1, Tmp2, &p1); - - for (i=0; i < p16 -> nOutputs; i++) { - Output[i] = LinearInterp(rk, Tmp1[i], Tmp2[i]); - } -} - - -static -void Eval7InputsFloat(cmsContext ContextID, const cmsFloat32Number Input[], - cmsFloat32Number Output[], - const cmsInterpParams* p) -{ - const cmsFloat32Number* LutTable = (cmsFloat32Number*) p -> Table; - cmsFloat32Number rest; - cmsFloat32Number pk; - int k0, K0, K1; - const cmsFloat32Number* T; - cmsUInt32Number i; - cmsFloat32Number Tmp1[MAX_STAGE_CHANNELS], Tmp2[MAX_STAGE_CHANNELS]; - cmsInterpParams p1; - - pk = fclamp(Input[0]) * p->Domain[0]; - k0 = _cmsQuickFloor(pk); - rest = pk - (cmsFloat32Number) k0; - - K0 = p -> opta[6] * k0; - K1 = K0 + (fclamp(Input[0]) >= 1.0 ? 0 : p->opta[6]); - - p1 = *p; - memmove(&p1.Domain[0], &p ->Domain[1], 6*sizeof(cmsUInt32Number)); - - T = LutTable + K0; - p1.Table = T; - - Eval6InputsFloat(ContextID, Input + 1, Tmp1, &p1); - - T = LutTable + K1; - p1.Table = T; - - Eval6InputsFloat(ContextID, Input + 1, Tmp2, &p1); - - - for (i=0; i < p -> nOutputs; i++) { - - cmsFloat32Number y0 = Tmp1[i]; - cmsFloat32Number y1 = Tmp2[i]; - - Output[i] = y0 + (y1 - y0) * rest; - - } -} - -static CMS_NO_SANITIZE -void Eval8Inputs(cmsContext ContextID, - CMSREGISTER const cmsUInt16Number Input[], - CMSREGISTER cmsUInt16Number Output[], - CMSREGISTER const cmsInterpParams* p16) -{ - const cmsUInt16Number* LutTable = (cmsUInt16Number*) p16 -> Table; - cmsS15Fixed16Number fk; - cmsS15Fixed16Number k0, rk; - int K0, K1; - const cmsUInt16Number* T; - cmsUInt32Number i; - cmsUInt16Number Tmp1[MAX_STAGE_CHANNELS], Tmp2[MAX_STAGE_CHANNELS]; - cmsInterpParams p1; - - fk = _cmsToFixedDomain((cmsS15Fixed16Number) Input[0] * p16 -> Domain[0]); - k0 = FIXED_TO_INT(fk); - rk = FIXED_REST_TO_INT(fk); - - K0 = p16 -> opta[7] * k0; - K1 = p16 -> opta[7] * (k0 + (Input[0] != 0xFFFFU ? 1 : 0)); - - p1 = *p16; - memmove(&p1.Domain[0], &p16 ->Domain[1], 7*sizeof(cmsUInt32Number)); - - T = LutTable + K0; - p1.Table = T; - - Eval7Inputs(ContextID, Input + 1, Tmp1, &p1); - - T = LutTable + K1; - p1.Table = T; - Eval7Inputs(ContextID, Input + 1, Tmp2, &p1); - - for (i=0; i < p16 -> nOutputs; i++) { - Output[i] = LinearInterp(rk, Tmp1[i], Tmp2[i]); - } +#define EVAL_FNS(N,NM) static CMS_NO_SANITIZE \ +void Eval##N##Inputs(cmsContext contextID, CMSREGISTER const cmsUInt16Number Input[], CMSREGISTER cmsUInt16Number Output[], CMSREGISTER const cmsInterpParams* p16) \ +{\ + const cmsUInt16Number* LutTable = (cmsUInt16Number*) p16 -> Table;\ + cmsS15Fixed16Number fk;\ + cmsS15Fixed16Number k0, rk;\ + int K0, K1;\ + const cmsUInt16Number* T;\ + cmsUInt32Number i;\ + cmsUInt16Number Tmp1[MAX_STAGE_CHANNELS], Tmp2[MAX_STAGE_CHANNELS];\ + cmsInterpParams p1;\ +\ + fk = _cmsToFixedDomain((cmsS15Fixed16Number) Input[0] * p16 -> Domain[0]);\ + k0 = FIXED_TO_INT(fk);\ + rk = FIXED_REST_TO_INT(fk);\ +\ + K0 = p16 -> opta[NM] * k0;\ + K1 = p16 -> opta[NM] * (k0 + (Input[0] != 0xFFFFU ? 1 : 0));\ +\ + p1 = *p16;\ + memmove(&p1.Domain[0], &p16 ->Domain[1], NM*sizeof(cmsUInt32Number));\ +\ + T = LutTable + K0;\ + p1.Table = T;\ +\ + Eval##NM##Inputs(contextID, Input + 1, Tmp1, &p1);\ +\ + T = LutTable + K1;\ + p1.Table = T;\ +\ + Eval##NM##Inputs(contextID, Input + 1, Tmp2, &p1);\ +\ + for (i=0; i < p16 -> nOutputs; i++) {\ +\ + Output[i] = LinearInterp(rk, Tmp1[i], Tmp2[i]);\ + }\ +}\ +\ +static void Eval##N##InputsFloat(cmsContext contextID,\ + const cmsFloat32Number Input[], \ + cmsFloat32Number Output[],\ + const cmsInterpParams * p)\ +{\ + const cmsFloat32Number* LutTable = (cmsFloat32Number*) p -> Table;\ + cmsFloat32Number rest;\ + cmsFloat32Number pk;\ + int k0, K0, K1;\ + const cmsFloat32Number* T;\ + cmsUInt32Number i;\ + cmsFloat32Number Tmp1[MAX_STAGE_CHANNELS], Tmp2[MAX_STAGE_CHANNELS];\ + cmsInterpParams p1;\ +\ + pk = fclamp(Input[0]) * p->Domain[0];\ + k0 = _cmsQuickFloor(pk);\ + rest = pk - (cmsFloat32Number) k0;\ +\ + K0 = p -> opta[NM] * k0;\ + K1 = K0 + (fclamp(Input[0]) >= 1.0 ? 0 : p->opta[NM]);\ +\ + p1 = *p;\ + memmove(&p1.Domain[0], &p ->Domain[1], NM*sizeof(cmsUInt32Number));\ +\ + T = LutTable + K0;\ + p1.Table = T;\ +\ + Eval##NM##InputsFloat(contextID, Input + 1, Tmp1, &p1);\ +\ + T = LutTable + K1;\ + p1.Table = T;\ +\ + Eval##NM##InputsFloat(contextID, Input + 1, Tmp2, &p1);\ +\ + for (i=0; i < p -> nOutputs; i++) {\ +\ + cmsFloat32Number y0 = Tmp1[i];\ + cmsFloat32Number y1 = Tmp2[i];\ +\ + Output[i] = y0 + (y1 - y0) * rest;\ + }\ } - -static -void Eval8InputsFloat(cmsContext ContextID, const cmsFloat32Number Input[], - cmsFloat32Number Output[], - const cmsInterpParams* p) -{ - const cmsFloat32Number* LutTable = (cmsFloat32Number*) p -> Table; - cmsFloat32Number rest; - cmsFloat32Number pk; - int k0, K0, K1; - const cmsFloat32Number* T; - cmsUInt32Number i; - cmsFloat32Number Tmp1[MAX_STAGE_CHANNELS], Tmp2[MAX_STAGE_CHANNELS]; - cmsInterpParams p1; - - pk = fclamp(Input[0]) * p->Domain[0]; - k0 = _cmsQuickFloor(pk); - rest = pk - (cmsFloat32Number) k0; - - K0 = p -> opta[7] * k0; - K1 = K0 + (fclamp(Input[0]) >= 1.0 ? 0 : p->opta[7]); - - p1 = *p; - memmove(&p1.Domain[0], &p ->Domain[1], 7*sizeof(cmsUInt32Number)); - - T = LutTable + K0; - p1.Table = T; - - Eval7InputsFloat(ContextID, Input + 1, Tmp1, &p1); - - T = LutTable + K1; - p1.Table = T; - - Eval7InputsFloat(ContextID, Input + 1, Tmp2, &p1); - - - for (i=0; i < p -> nOutputs; i++) { - - cmsFloat32Number y0 = Tmp1[i]; - cmsFloat32Number y1 = Tmp2[i]; - - Output[i] = y0 + (y1 - y0) * rest; - } -} +/** +* Thanks to Carles Llopis for the templating idea +*/ +EVAL_FNS(5, 4) +EVAL_FNS(6, 5) +EVAL_FNS(7, 6) +EVAL_FNS(8, 7) +EVAL_FNS(9, 8) +EVAL_FNS(10, 9) +EVAL_FNS(11, 10) +EVAL_FNS(12, 11) +EVAL_FNS(13, 12) +EVAL_FNS(14, 13) +EVAL_FNS(15, 14) // The default factory static @@ -1530,6 +1275,53 @@ cmsInterpFunction DefaultInterpolatorsFactory(cmsUInt32Number nInputChannels, cm Interpolation.Lerp16 = Eval8Inputs; break; + case 9: + if (IsFloat) + Interpolation.LerpFloat = Eval9InputsFloat; + else + Interpolation.Lerp16 = Eval9Inputs; + break; + + case 10: + if (IsFloat) + Interpolation.LerpFloat = Eval10InputsFloat; + else + Interpolation.Lerp16 = Eval10Inputs; + break; + + case 11: + if (IsFloat) + Interpolation.LerpFloat = Eval11InputsFloat; + else + Interpolation.Lerp16 = Eval11Inputs; + break; + + case 12: + if (IsFloat) + Interpolation.LerpFloat = Eval12InputsFloat; + else + Interpolation.Lerp16 = Eval12Inputs; + break; + + case 13: + if (IsFloat) + Interpolation.LerpFloat = Eval13InputsFloat; + else + Interpolation.Lerp16 = Eval13Inputs; + break; + + case 14: + if (IsFloat) + Interpolation.LerpFloat = Eval14InputsFloat; + else + Interpolation.Lerp16 = Eval14Inputs; + break; + + case 15: + if (IsFloat) + Interpolation.LerpFloat = Eval15InputsFloat; + else + Interpolation.Lerp16 = Eval15Inputs; break; default: diff --git a/lcms2mt/src/cmsio0.c b/lcms2mt/src/cmsio0.c index 0dd6ca120..83b374453 100644 --- a/lcms2mt/src/cmsio0.c +++ b/lcms2mt/src/cmsio0.c @@ -266,7 +266,7 @@ cmsIOHANDLER* CMSEXPORT cmsOpenIOhandlerFromMem(cmsContext ContextID, void *Buff _cmsFree(ContextID, fm); _cmsFree(ContextID, iohandler); - cmsSignalError(ContextID, cmsERROR_READ, "Couldn't allocate %ld bytes for profile", size); + cmsSignalError(ContextID, cmsERROR_READ, "Couldn't allocate %ld bytes for profile", (long) size); return NULL; } @@ -1207,25 +1207,28 @@ cmsBool SaveTags(cmsContext ContextID, _cmsICCPROFILE* Icc, _cmsICCPROFILE* File // In this case a blind copy of the block data is performed if (FileOrig != NULL && Icc -> TagOffsets[i]) { - cmsUInt32Number TagSize = FileOrig -> TagSizes[i]; - cmsUInt32Number TagOffset = FileOrig -> TagOffsets[i]; - void* Mem; + if (FileOrig->IOhandler != NULL) + { + cmsUInt32Number TagSize = FileOrig->TagSizes[i]; + cmsUInt32Number TagOffset = FileOrig->TagOffsets[i]; + void* Mem; - if (!FileOrig ->IOhandler->Seek(ContextID, FileOrig ->IOhandler, TagOffset)) return FALSE; + if (!FileOrig ->IOhandler->Seek(ContextID, FileOrig ->IOhandler, TagOffset)) return FALSE; - Mem = _cmsMalloc(ContextID, TagSize); - if (Mem == NULL) return FALSE; + Mem = _cmsMalloc(ContextID, TagSize); + if (Mem == NULL) return FALSE; - if (FileOrig ->IOhandler->Read(ContextID, FileOrig->IOhandler, Mem, TagSize, 1) != 1) return FALSE; - if (!io ->Write(ContextID, io, TagSize, Mem)) return FALSE; - _cmsFree(ContextID, Mem); + if (FileOrig ->IOhandler->Read(ContextID, FileOrig->IOhandler, Mem, TagSize, 1) != 1) return FALSE; + if (!io ->Write(ContextID, io, TagSize, Mem)) return FALSE; + _cmsFree(ContextID, Mem); - Icc -> TagSizes[i] = (io ->UsedSpace - Begin); + Icc->TagSizes[i] = (io->UsedSpace - Begin); - // Align to 32 bit boundary. - if (! _cmsWriteAlignment(ContextID, io)) - return FALSE; + // Align to 32 bit boundary. + if (! _cmsWriteAlignment(ContextID, io)) + return FALSE; + } } continue; diff --git a/lcms2mt/src/cmslut.c b/lcms2mt/src/cmslut.c index 241b6ae88..5c861004a 100644 --- a/lcms2mt/src/cmslut.c +++ b/lcms2mt/src/cmslut.c @@ -397,8 +397,7 @@ cmsStage* CMSEXPORT cmsStageAllocMatrix(cmsContext ContextID, cmsUInt32Number R NewElem = (_cmsStageMatrixData*) _cmsMallocZero(ContextID, sizeof(_cmsStageMatrixData)); if (NewElem == NULL) goto Error; - NewMPE ->Data = (void*) NewElem; - + NewMPE->Data = (void*)NewElem; NewElem ->Double = (cmsFloat64Number*) _cmsCalloc(ContextID, n, sizeof(cmsFloat64Number)); if (NewElem->Double == NULL) goto Error; @@ -407,7 +406,6 @@ cmsStage* CMSEXPORT cmsStageAllocMatrix(cmsContext ContextID, cmsUInt32Number R NewElem ->Double[i] = Matrix[i]; } - if (Offset != NULL) { NewElem ->Offset = (cmsFloat64Number*) _cmsCalloc(ContextID, Rows, sizeof(cmsFloat64Number)); @@ -416,7 +414,6 @@ cmsStage* CMSEXPORT cmsStageAllocMatrix(cmsContext ContextID, cmsUInt32Number R for (i=0; i < Rows; i++) { NewElem ->Offset[i] = Offset[i]; } - } return NewMPE; @@ -1346,7 +1343,7 @@ void _LUTeval16(cmsContext ContextID, CMSREGISTER const cmsUInt16Number In[], CM // Does evaluate the LUT on cmsFloat32Number-basis. static -void _LUTevalFloat(cmsContext ContextID, CMSREGISTER const cmsFloat32Number In[], CMSREGISTER cmsFloat32Number Out[], const void* D) +void _LUTevalFloat(cmsContext ContextID, const cmsFloat32Number In[], cmsFloat32Number Out[], const void* D) { cmsPipeline* lut = (cmsPipeline*) D; cmsStage *mpe; @@ -1663,8 +1660,9 @@ cmsUInt32Number CMSEXPORT cmsPipelineStageCount(cmsContext ContextID, const cmsP // This function may be used to set the optional evaluator and a block of private data. If private data is being used, an optional // duplicator and free functions should also be specified in order to duplicate the LUT construct. Use NULL to inhibit such functionality. -void CMSEXPORT _cmsPipelineSetOptimizationParameters(cmsContext ContextID, cmsPipeline* Lut, - _cmsOPTeval16Fn Eval16, +void CMSEXPORT _cmsPipelineSetOptimizationParameters(cmsContext ContextID, + cmsPipeline* Lut, + _cmsPipelineEval16Fn Eval16, void* PrivateData, _cmsFreeUserDataFn FreePrivateDataFn, _cmsDupUserDataFn DupPrivateDataFn) diff --git a/lcms2mt/src/cmsnamed.c b/lcms2mt/src/cmsnamed.c index cd751b47f..fa2555293 100644 --- a/lcms2mt/src/cmsnamed.c +++ b/lcms2mt/src/cmsnamed.c @@ -178,12 +178,16 @@ cmsBool AddMLUBlock(cmsContext ContextID, cmsMLU* mlu, cmsUInt32Number size, con // Convert from a 3-char code to a cmsUInt16Number. It is done in this way because some // compilers don't properly align beginning of strings - static cmsUInt16Number strTo16(const char str[3]) { - const cmsUInt8Number* ptr8 = (const cmsUInt8Number*)str; - cmsUInt16Number n = (cmsUInt16Number)(((cmsUInt16Number)ptr8[0] << 8) | ptr8[1]); + const cmsUInt8Number* ptr8; + cmsUInt16Number n; + + // For non-existent strings + if (str == NULL) return 0; + ptr8 = (const cmsUInt8Number*)str; + n = (cmsUInt16Number)(((cmsUInt16Number)ptr8[0] << 8) | ptr8[1]); return n; } @@ -198,6 +202,7 @@ void strFrom16(char str[3], cmsUInt16Number n) } // Add an ASCII entry. Do not add any \0 termination (ICC1v43_2010-12.pdf page 61) +// In the case the user explicitely sets an empty string, we force a \0 cmsBool CMSEXPORT cmsMLUsetASCII(cmsContext ContextID, cmsMLU* mlu, const char LanguageCode[3], const char CountryCode[3], const char* ASCIIString) { cmsUInt32Number i, len = (cmsUInt32Number) strlen(ASCIIString); @@ -208,6 +213,12 @@ cmsBool CMSEXPORT cmsMLUsetASCII(cmsContext ContextID, cmsMLU* mlu, const char L if (mlu == NULL) return FALSE; + // len == 0 would prevent operation, so we set a empty string pointing to zero + if (len == 0) + { + len = 1; + } + WStr = (wchar_t*) _cmsCalloc(ContextID, len, sizeof(wchar_t)); if (WStr == NULL) return FALSE; @@ -245,6 +256,9 @@ cmsBool CMSEXPORT cmsMLUsetWide(cmsContext ContextID, cmsMLU* mlu, const char L if (WideString == NULL) return FALSE; len = (cmsUInt32Number) (mywcslen(WideString)) * sizeof(wchar_t); + if (len == 0) + len = sizeof(wchar_t); + return AddMLUBlock(ContextID, mlu, len, WideString, Lang, Cntry); } diff --git a/lcms2mt/src/cmsopt.c b/lcms2mt/src/cmsopt.c index 7fb5e0293..8fca60f84 100644 --- a/lcms2mt/src/cmsopt.c +++ b/lcms2mt/src/cmsopt.c @@ -379,7 +379,20 @@ Prelin16Data* PrelinOpt16alloc(cmsContext ContextID, p16 -> EvalCurveOut16 = (_cmsInterpFn16*) _cmsCalloc(ContextID, nOutputs, sizeof(_cmsInterpFn16)); + if (p16->EvalCurveOut16 == NULL) + { + _cmsFree(ContextID, p16); + return NULL; + } + p16 -> ParamsCurveOut16 = (cmsInterpParams**) _cmsCalloc(ContextID, nOutputs, sizeof(cmsInterpParams* )); + if (p16->ParamsCurveOut16 == NULL) + { + + _cmsFree(ContextID, p16->EvalCurveOut16); + _cmsFree(ContextID, p16); + return NULL; + } for (i=0; i < nOutputs; i++) { @@ -406,7 +419,10 @@ Prelin16Data* PrelinOpt16alloc(cmsContext ContextID, // Sampler implemented by another LUT. This is a clean way to precalculate the devicelink 3D CLUT for // almost any transform. We use floating point precision and then convert from floating point to 16 bits. static -cmsInt32Number XFormSampler16(cmsContext ContextID, CMSREGISTER const cmsUInt16Number In[], CMSREGISTER cmsUInt16Number Out[], CMSREGISTER void* Cargo) +cmsInt32Number XFormSampler16(cmsContext ContextID, + CMSREGISTER const cmsUInt16Number In[], + CMSREGISTER cmsUInt16Number Out[], + CMSREGISTER void* Cargo) { cmsPipeline* Lut = (cmsPipeline*) Cargo; cmsFloat32Number InFloat[cmsMAXCHANNELS], OutFloat[cmsMAXCHANNELS]; @@ -765,7 +781,7 @@ Error: if (DataSetIn == NULL && DataSetOut == NULL) { - _cmsPipelineSetOptimizationParameters(ContextID, Dest, (_cmsOPTeval16Fn) DataCLUT->Params->Interpolation.Lerp16, DataCLUT->Params, NULL, NULL); + _cmsPipelineSetOptimizationParameters(ContextID, Dest, (_cmsPipelineEval16Fn) DataCLUT->Params->Interpolation.Lerp16, DataCLUT->Params, NULL, NULL); } else { @@ -929,9 +945,9 @@ void PrelinEval8(cmsContext ContextID, g = (cmsUInt8Number) (Input[1] >> 8); b = (cmsUInt8Number) (Input[2] >> 8); - X0 = X1 = (cmsS15Fixed16Number) p8->X0[r]; - Y0 = Y1 = (cmsS15Fixed16Number) p8->Y0[g]; - Z0 = Z1 = (cmsS15Fixed16Number) p8->Z0[b]; + X0 = (cmsS15Fixed16Number) p8->X0[r]; + Y0 = (cmsS15Fixed16Number) p8->Y0[g]; + Z0 = (cmsS15Fixed16Number) p8->Z0[b]; rx = p8 ->rx[r]; ry = p8 ->ry[g]; @@ -1900,7 +1916,7 @@ cmsBool _cmsRegisterOptimizationPlugin(cmsContext ContextID, cmsPluginBase* Dat } // The entry point for LUT optimization -cmsBool _cmsOptimizePipeline(cmsContext ContextID, +cmsBool CMSEXPORT _cmsOptimizePipeline(cmsContext ContextID, cmsPipeline** PtrLut, cmsUInt32Number Intent, cmsUInt32Number* InputFormat, diff --git a/lcms2mt/src/cmspack.c b/lcms2mt/src/cmspack.c index 150c081db..01065c0d3 100644 --- a/lcms2mt/src/cmspack.c +++ b/lcms2mt/src/cmspack.c @@ -2904,7 +2904,7 @@ cmsUInt8Number* UnrollHalfTo16(cmsContext ContextID, if (Reverse) v = maximum - v; - wIn[index] = _cmsQuickSaturateWord(v * maximum); + wIn[index] = _cmsQuickSaturateWord((cmsFloat64Number) v * maximum); } diff --git a/lcms2mt/src/cmspcs.c b/lcms2mt/src/cmspcs.c index 743d479fd..7a3e30970 100644 --- a/lcms2mt/src/cmspcs.c +++ b/lcms2mt/src/cmspcs.c @@ -668,7 +668,7 @@ cmsFloat64Number CMSEXPORT cmsCIE2000DeltaE(cmsContext ContextID, const cmsCIELa // This function returns a number of gridpoints to be used as LUT table. It assumes same number // of gripdpoints in all dimensions. Flags may override the choice. -cmsUInt32Number _cmsReasonableGridpointsByColorspace(cmsContext ContextID, cmsColorSpaceSignature Colorspace, cmsUInt32Number dwFlags) +cmsUInt32Number CMSEXPORT _cmsReasonableGridpointsByColorspace(cmsContext ContextID, cmsColorSpaceSignature Colorspace, cmsUInt32Number dwFlags) { cmsUInt32Number nChannels; diff --git a/lcms2mt/src/cmsplugin.c b/lcms2mt/src/cmsplugin.c index 206368c44..2a6e6b6bf 100644 --- a/lcms2mt/src/cmsplugin.c +++ b/lcms2mt/src/cmsplugin.c @@ -186,7 +186,7 @@ cmsBool CMSEXPORT _cmsReadFloat32Number(cmsContext ContextID, cmsIOHANDLER* io, return TRUE; #elif defined (__BORLANDC__) return TRUE; - #elif !defined(_MSC_VER) && !defined(HAVE_FPCLASSIFY) + #elif !defined(_MSC_VER) && (defined(__STDC_VERSION__) && __STDC_VERSION__ < 199901L) && !defined(HAVE_FPCLASSIFY) return TRUE; #else @@ -503,6 +503,7 @@ cmsBool CMSEXPORT _cmsIOPrintf(cmsContext ContextID, cmsIOHANDLER* io, const cha int len; cmsUInt8Number Buffer[2048]; cmsBool rc; + cmsUInt8Number* ptr; _cmsAssert(io != NULL); _cmsAssert(frm != NULL); @@ -515,6 +516,13 @@ cmsBool CMSEXPORT _cmsIOPrintf(cmsContext ContextID, cmsIOHANDLER* io, const cha return FALSE; // Truncated, which is a fatal error for us } + // setlocale may be active, no commas are needed in PS generator + // and PS generator is our only client + for (ptr = Buffer; *ptr; ptr++) + { + if (*ptr == ',') *ptr = '.'; + } + rc = io ->Write(ContextID, io, (cmsUInt32Number) len, Buffer); va_end(args); @@ -675,15 +683,21 @@ struct _cmsContext_struct* _cmsGetContext(cmsContext ContextID) return &globalContext; // Search + _cmsEnterCriticalSectionPrimitive(&_cmsContextPoolHeadMutex); + for (ctx = _cmsContextPoolHead; ctx != NULL; ctx = ctx ->Next) { // Found it? - if (id == ctx) - return ctx; // New-style context, + if (id == ctx) + { + _cmsLeaveCriticalSectionPrimitive(&_cmsContextPoolHeadMutex); + return ctx; // New-style context + } } + _cmsLeaveCriticalSectionPrimitive(&_cmsContextPoolHeadMutex); return &globalContext; } @@ -918,25 +932,6 @@ cmsContext CMSEXPORT cmsDupContext(cmsContext ContextID, void* NewUserData) } -/* -static -struct _cmsContext_struct* FindPrev(struct _cmsContext_struct* id) -{ - struct _cmsContext_struct* prev; - - // Search for previous - for (prev = _cmsContextPoolHead; - prev != NULL; - prev = prev ->Next) - { - if (prev ->Next == id) - return prev; - } - - return NULL; // List is empty or only one element! -} -*/ - // Frees any resources associated with the given context, // and destroys the context placeholder. // The ContextID can no longer be used in any THR operation. diff --git a/lcms2mt/src/cmsps2.c b/lcms2mt/src/cmsps2.c index 62558bfc3..bdaaf6d6e 100644 --- a/lcms2mt/src/cmsps2.c +++ b/lcms2mt/src/cmsps2.c @@ -529,9 +529,10 @@ void Emit1Gamma(cmsContext ContextID, cmsIOHANDLER* m, cmsToneCurve* Table, cons // Compare gamma table static -cmsBool GammaTableEquals(cmsUInt16Number* g1, cmsUInt16Number* g2, cmsUInt32Number nEntries) +cmsBool GammaTableEquals(cmsUInt16Number* g1, cmsUInt16Number* g2, cmsUInt32Number nG1, cmsUInt32Number nG2) { - return memcmp(g1, g2, nEntries* sizeof(cmsUInt16Number)) == 0; + if (nG1 != nG2) return FALSE; + return memcmp(g1, g2, nG1 * sizeof(cmsUInt16Number)) == 0; } @@ -547,12 +548,12 @@ void EmitNGamma(cmsContext ContextID, cmsIOHANDLER* m, cmsUInt32Number n, cmsTon { if (g[i] == NULL) return; // Error - if (i > 0 && GammaTableEquals(g[i-1]->Table16, g[i]->Table16, g[i]->nEntries)) { + if (i > 0 && GammaTableEquals(g[i-1]->Table16, g[i]->Table16, g[i-1]->nEntries, g[i]->nEntries)) { _cmsIOPrintf(ContextID, m, "/%s%d /%s%d load def\n", nameprefix, i, nameprefix, i-1); } else { - snprintf(buffer, sizeof(buffer), "%s%d", nameprefix, i); + snprintf(buffer, sizeof(buffer), "%s%d", nameprefix, (int) i); buffer[sizeof(buffer)-1] = '\0'; Emit1Gamma(ContextID, m, g[i], buffer); } @@ -807,7 +808,7 @@ int EmitCIEBasedDEF(cmsContext ContextID, cmsIOHANDLER* m, cmsPipeline* Pipeline if (cmsStageType(ContextID, mpe) == cmsSigCurveSetElemType) { - numchans = cmsStageOutputChannels(ContextID, mpe); + numchans = (int) cmsStageOutputChannels(ContextID, mpe); for (i = 0; i < numchans; ++i) { snprintf(buffer, sizeof(buffer), "lcms2gammaproc%d", i); buffer[sizeof(buffer) - 1] = '\0'; diff --git a/lcms2mt/src/cmssamp.c b/lcms2mt/src/cmssamp.c index c563fac6d..8fb1d1f6f 100644 --- a/lcms2mt/src/cmssamp.c +++ b/lcms2mt/src/cmssamp.c @@ -82,10 +82,10 @@ cmsBool BlackPointAsDarkerColorant(cmsContext ContextID, return FALSE; } - // Create a formatter which has n channels and floating point + // Create a formatter which has n channels and no floating point dwFormat = cmsFormatterForColorspaceOfProfile(ContextID, hInput, 2, FALSE); - // Try to get black by using black colorant + // Try to get black by using black colorant Space = cmsGetColorSpace(ContextID, hInput); // This function returns darker colorant in 16 bits for several spaces diff --git a/lcms2mt/src/cmstypes.c b/lcms2mt/src/cmstypes.c index 85256ef7a..1d8c2a383 100644 --- a/lcms2mt/src/cmstypes.c +++ b/lcms2mt/src/cmstypes.c @@ -1907,6 +1907,7 @@ cmsBool Type_LUT8_Write(cmsContext ContextID, struct _cms_typehandler_struct* s mpe = NewLUT -> Elements; if (mpe ->Type == cmsSigMatrixElemType) { + if (mpe->InputChannels != 3 || mpe->OutputChannels != 3) return FALSE; MatMPE = (_cmsStageMatrixData*) mpe ->Data; mpe = mpe -> Next; } @@ -1932,7 +1933,6 @@ cmsBool Type_LUT8_Write(cmsContext ContextID, struct _cms_typehandler_struct* s return FALSE; } - if (clut == NULL) clutPoints = 0; else @@ -1947,15 +1947,13 @@ cmsBool Type_LUT8_Write(cmsContext ContextID, struct _cms_typehandler_struct* s if (MatMPE != NULL) { - for (i = 0; i < n; i++) + for (i = 0; i < 9; i++) { if (!_cmsWrite15Fixed16Number(ContextID, io, MatMPE->Double[i])) return FALSE; } } else { - if (n != 9) return FALSE; - if (!_cmsWrite15Fixed16Number(ContextID, io, 1)) return FALSE; if (!_cmsWrite15Fixed16Number(ContextID, io, 0)) return FALSE; if (!_cmsWrite15Fixed16Number(ContextID, io, 0)) return FALSE; @@ -2178,9 +2176,9 @@ Error: // Some empty defaults are created for missing parts static -cmsBool Type_LUT16_Write(cmsContext ContextID, struct _cms_typehandler_struct* self, cmsIOHANDLER* io, void* Ptr, cmsUInt32Number nItems) +cmsBool Type_LUT16_Write(cmsContext ContextID, struct _cms_typehandler_struct* self, cmsIOHANDLER* io, void* Ptr, cmsUInt32Number nItems) { - cmsUInt32Number nTabSize, n; + cmsUInt32Number nTabSize; cmsPipeline* NewLUT = (cmsPipeline*) Ptr; cmsStage* mpe; _cmsStageToneCurvesData* PreMPE = NULL, *PostMPE = NULL; @@ -2194,6 +2192,7 @@ cmsBool Type_LUT16_Write(cmsContext ContextID, struct _cms_typehandler_struct* if (mpe != NULL && mpe ->Type == cmsSigMatrixElemType) { MatMPE = (_cmsStageMatrixData*) mpe ->Data; + if (mpe->InputChannels != 3 || mpe->OutputChannels != 3) return FALSE; mpe = mpe -> Next; } @@ -2232,11 +2231,9 @@ cmsBool Type_LUT16_Write(cmsContext ContextID, struct _cms_typehandler_struct* if (!_cmsWriteUInt8Number(ContextID, io, (cmsUInt8Number) clutPoints)) return FALSE; if (!_cmsWriteUInt8Number(ContextID, io, 0)) return FALSE; // Padding - n = NewLUT->InputChannels * NewLUT->OutputChannels; - if (MatMPE != NULL) { - for (i = 0; i < n; i++) + for (i = 0; i < 9; i++) { if (!_cmsWrite15Fixed16Number(ContextID, io, MatMPE->Double[i])) return FALSE; } @@ -2244,8 +2241,6 @@ cmsBool Type_LUT16_Write(cmsContext ContextID, struct _cms_typehandler_struct* } else { - if (n != 9) return FALSE; - if (!_cmsWrite15Fixed16Number(ContextID, io, 1)) return FALSE; if (!_cmsWrite15Fixed16Number(ContextID, io, 0)) return FALSE; if (!_cmsWrite15Fixed16Number(ContextID, io, 0)) return FALSE; @@ -3048,6 +3043,9 @@ void *Type_ColorantTable_Read(cmsContext ContextID, struct _cms_typehandler_stru } List = cmsAllocNamedColorList(ContextID, Count, 0, "", ""); + if (List == NULL) + return NULL; + for (i=0; i < Count; i++) { if (io ->Read(ContextID, io,Name, 32, 1) != 1) goto Error; diff --git a/lcms2mt/src/cmsxform.c b/lcms2mt/src/cmsxform.c index e9b34341d..7440e6786 100644 --- a/lcms2mt/src/cmsxform.c +++ b/lcms2mt/src/cmsxform.c @@ -269,7 +269,7 @@ void FloatXFORM(cmsContext ContextID, _cmsTRANSFORM* p, strideIn = 0; strideOut = 0; memset(fIn, 0, sizeof(fIn)); - memset(fOut, 0, sizeof(fIn)); + memset(fOut, 0, sizeof(fOut)); for (i = 0; i < LineCount; i++) { @@ -966,7 +966,7 @@ cmsBool _cmsRegisterTransformPlugin(cmsContext ContextID, cmsPluginBase* Data) if (fl == NULL) return FALSE; // Check for full xform plug-ins previous to 2.8, we would need an adapter in that case - if (Plugin->base.ExpectedVersion < 2080-2000) { + if (Plugin->base.ExpectedVersion < 2080) { fl->OldXform = TRUE; } @@ -1014,6 +1014,12 @@ void CMSEXPORT _cmsGetTransformFormattersFloat(struct _cmstransform_struct *CMMc if (ToOutput) *ToOutput = CMMcargo ->ToOutputFloat; } +// returns original flags +cmsUInt32Number CMSEXPORT _cmsGetTransformFlags(struct _cmstransform_struct* CMMcargo) +{ + _cmsAssert(CMMcargo != NULL); + return CMMcargo->core->dwOriginalFlags; +} void _cmsFindFormatter(_cmsTRANSFORM* p, cmsUInt32Number InputFormat, cmsUInt32Number OutputFormat, cmsUInt32Number dwFlags) @@ -1153,43 +1159,46 @@ _cmsTRANSFORM* AllocEmptyTransform(cmsContext ContextID, cmsPipeline* lut, p->core->Lut = lut; // Let's see if any plug-in want to do the transform by itself - if (core->Lut != NULL && !(*dwFlags & cmsFLAGS_NOOPTIMIZE)) { - - for (Plugin = ctx->TransformCollection; - Plugin != NULL; - Plugin = Plugin->Next) { - - if (Plugin->Factory(ContextID, &p->xform, &core->UserData, &core->FreeUserData, &core->Lut, InputFormat, OutputFormat, dwFlags)) { - - // Last plugin in the declaration order takes control. We just keep - // the original parameters as a logging. - // Note that cmsFLAGS_CAN_CHANGE_FORMATTER is not set, so by default - // an optimized transform is not reusable. The plug-in can, however, change - // the flags and make it suitable. - - p->InputFormat = *InputFormat; - p->OutputFormat = *OutputFormat; - core->dwOriginalFlags = *dwFlags; - - // Fill the formatters just in case the optimized routine is interested. - // No error is thrown if the formatter doesn't exist. It is up to the optimization - // factory to decide what to do in those cases. - p->FromInput = _cmsGetFormatter(ContextID, *InputFormat, cmsFormatterInput, CMS_PACK_FLAGS_16BITS).Fmt16; - p->ToOutput = _cmsGetFormatter(ContextID, *OutputFormat, cmsFormatterOutput, CMS_PACK_FLAGS_16BITS).Fmt16; - p->FromInputFloat = _cmsGetFormatter(ContextID, *InputFormat, cmsFormatterInput, CMS_PACK_FLAGS_FLOAT).FmtFloat; - p->ToOutputFloat = _cmsGetFormatter(ContextID, *OutputFormat, cmsFormatterOutput, CMS_PACK_FLAGS_FLOAT).FmtFloat; - - // Save the day? (Ignore the warning) - if (Plugin->OldXform) { - p->OldXform = (_cmsTransformFn)(void*) p->xform; - p->xform = _cmsTransform2toTransformAdaptor; - } - return p; - } - } - - // Not suitable for the transform plug-in, let's check the pipeline plug-in - _cmsOptimizePipeline(ContextID, &core->Lut, Intent, InputFormat, OutputFormat, dwFlags); + if (core->Lut != NULL) { + if (!(*dwFlags & cmsFLAGS_NOOPTIMIZE)) { + + for (Plugin = ctx->TransformCollection; + Plugin != NULL; + Plugin = Plugin->Next) { + + if (Plugin->Factory(ContextID, &p->xform, &core->UserData, &core->FreeUserData, &core->Lut, InputFormat, OutputFormat, dwFlags)) { + + // Last plugin in the declaration order takes control. We just keep + // the original parameters as a logging. + // Note that cmsFLAGS_CAN_CHANGE_FORMATTER is not set, so by default + // an optimized transform is not reusable. The plug-in can, however, change + // the flags and make it suitable. + + p->InputFormat = *InputFormat; + p->OutputFormat = *OutputFormat; + core->dwOriginalFlags = *dwFlags; + + // Fill the formatters just in case the optimized routine is interested. + // No error is thrown if the formatter doesn't exist. It is up to the optimization + // factory to decide what to do in those cases. + p->FromInput = _cmsGetFormatter(ContextID, *InputFormat, cmsFormatterInput, CMS_PACK_FLAGS_16BITS).Fmt16; + p->ToOutput = _cmsGetFormatter(ContextID, *OutputFormat, cmsFormatterOutput, CMS_PACK_FLAGS_16BITS).Fmt16; + p->FromInputFloat = _cmsGetFormatter(ContextID, *InputFormat, cmsFormatterInput, CMS_PACK_FLAGS_FLOAT).FmtFloat; + p->ToOutputFloat = _cmsGetFormatter(ContextID, *OutputFormat, cmsFormatterOutput, CMS_PACK_FLAGS_FLOAT).FmtFloat; + + // Save the day? (Ignore the warning) + if (Plugin->OldXform) { + p->OldXform = (_cmsTransformFn)(void*) p->xform; + p->xform = _cmsTransform2toTransformAdaptor; + } + + return p; + } + } + } + + // Not suitable for the transform plug-in, let's check the pipeline plug-in + _cmsOptimizePipeline(ContextID, &core->Lut, Intent, InputFormat, OutputFormat, dwFlags); } // Check whatever this is a true floating point transform @@ -1599,7 +1608,7 @@ cmsUInt32Number CMSEXPORT cmsGetTransformOutputFormat(cmsContext ContextID, cmsH return xform->OutputFormat; } -cmsHTRANSFORM CMSEXPORT cmsCloneTransformChangingFormats(cmsContext ContextID, +cmsHTRANSFORM cmsCloneTransformChangingFormats(cmsContext ContextID, const cmsHTRANSFORM hTransform, cmsUInt32Number InputFormat, cmsUInt32Number OutputFormat) diff --git a/lcms2mt/src/extra_xform.h b/lcms2mt/src/extra_xform.h index e42a81daa..51dd0e05b 100644 --- a/lcms2mt/src/extra_xform.h +++ b/lcms2mt/src/extra_xform.h @@ -189,13 +189,13 @@ void FUNCTION_NAME(cmsContext ContextID, XFORM_TYPE wOut[cmsMAXCHANNELS]; #endif #ifdef GAMUTCHECK - _cmsOPTeval16Fn evalGamut = core->GamutCheck->Eval16Fn; + _cmsPipelineEval16Fn evalGamut = core->GamutCheck->Eval16Fn; #endif /* GAMUTCHECK */ #ifdef XFORM_FLOAT _cmsPipelineEvalFloatFn eval = core->Lut->EvalFloatFn; const cmsPipeline *data = core->Lut; #else - _cmsOPTeval16Fn eval = core->Lut->Eval16Fn; + _cmsPipelineEval16Fn eval = core->Lut->Eval16Fn; void *data = core->Lut->Data; #endif cmsUInt32Number bppi = Stride->BytesPerPlaneIn; diff --git a/lcms2mt/src/lcms2_internal.h b/lcms2mt/src/lcms2_internal.h index 175b3c998..da205ebf1 100644 --- a/lcms2mt/src/lcms2_internal.h +++ b/lcms2mt/src/lcms2_internal.h @@ -116,12 +116,13 @@ #define isinf(x) (!_finite((x))) # endif -#else -# if !defined(HAVE_ISINF) -# if !defined(isinf) -# define isinf(x) (!finite((x))) -# endif -# endif +#if !defined(_MSC_VER) && (defined(__STDC_VERSION__) && __STDC_VERSION__ < 199901L) + #if !defined(isinf) + #define isinf(x) (!finite((x))) + #endif +#endif + + #endif // A fast way to convert from/to 16 <-> 8 bits @@ -903,13 +904,7 @@ cmsStage* _cmsStageClipNegatives(cmsContext ContextID, // For curve set only -cmsToneCurve** _cmsStageGetPtrToCurveSet(const cmsStage* mpe); - - -// Pipeline Evaluator (in floating point) -typedef void (* _cmsPipelineEvalFloatFn)(cmsContext ContextID, const cmsFloat32Number In[], - cmsFloat32Number Out[], - const void* Data); +cmsToneCurve** _cmsStageGetPtrToCurveSet(const cmsStage* mpe); struct _cmsPipeline_struct { @@ -919,7 +914,7 @@ struct _cmsPipeline_struct { // Data & evaluators void *Data; - _cmsOPTeval16Fn Eval16Fn; + _cmsPipelineEval16Fn Eval16Fn; _cmsPipelineEvalFloatFn EvalFloatFn; _cmsFreeUserDataFn FreeDataFn; _cmsDupUserDataFn DupDataFn; @@ -963,14 +958,15 @@ cmsSEQ* _cmsCompileProfileSequence(cmsContext ContextID, cmsUInt32Number nProfil // LUT optimization ------------------------------------------------------------------------------------------------ CMSCHECKPOINT cmsUInt16Number CMSEXPORT _cmsQuantizeVal(cmsFloat64Number i, cmsUInt32Number MaxSamples); -cmsUInt32Number _cmsReasonableGridpointsByColorspace(cmsContext ContextID, cmsColorSpaceSignature Colorspace, cmsUInt32Number dwFlags); + +CMSAPI cmsUInt32Number CMSEXPORT _cmsReasonableGridpointsByColorspace(cmsContext ContextID, cmsColorSpaceSignature Colorspace, cmsUInt32Number dwFlags); cmsBool _cmsEndPointsBySpace(cmsColorSpaceSignature Space, cmsUInt16Number **White, cmsUInt16Number **Black, cmsUInt32Number *nOutputs); -cmsBool _cmsOptimizePipeline(cmsContext ContextID, +CMSAPI cmsBool CMSEXPORT _cmsOptimizePipeline(cmsContext ContextID, cmsPipeline** Lut, cmsUInt32Number Intent, cmsUInt32Number* InputFormat, diff --git a/lcms2mt/src/lcms2mt.def b/lcms2mt/src/lcms2mt.def index 0703fed88..8f8033a96 100644 --- a/lcms2mt/src/lcms2mt.def +++ b/lcms2mt/src/lcms2mt.def @@ -344,3 +344,4 @@ cmsMD5add = cmsMD5add cmsMD5alloc = cmsMD5alloc cmsMD5finish = cmsMD5finish _cmsComputeInterpParams = _cmsComputeInterpParams +cmsGetToneCurveParams = cmsGetToneCurveParams |