diff -Nru lcms2-2.5/aclocal.m4 lcms2-2.6/aclocal.m4 --- lcms2-2.5/aclocal.m4 2013-06-27 16:01:28.000000000 +0000 +++ lcms2-2.6/aclocal.m4 2014-03-17 16:09:30.000000000 +0000 @@ -9436,3 +9436,4 @@ AC_SUBST([am__untar]) ]) # _AM_PROG_TAR +m4_include([m4/acx_pthread.m4]) diff -Nru lcms2-2.5/AUTHORS lcms2-2.6/AUTHORS --- lcms2-2.5/AUTHORS 2013-06-27 16:01:28.000000000 +0000 +++ lcms2-2.6/AUTHORS 2014-03-17 16:09:30.000000000 +0000 @@ -30,13 +30,18 @@ Christian Schmitz XhmikosR Stanislav Brabec (SuSe) +Leonhard Gruenschloss (Google) +Patrick Noffke +Christopher James Halse Rogers +John Hein Special Thanks -------------- +Artifex software Jan Morovic Jos Vernon (WebSupergoo) Harald Schneider (Maxon) Christian Albrecht Dimitrios Anastassakis Lemke Software -Tim Zaman \ No newline at end of file +Tim Zaman diff -Nru lcms2-2.5/autogen.sh lcms2-2.6/autogen.sh --- lcms2-2.5/autogen.sh 2013-06-27 16:01:28.000000000 +0000 +++ lcms2-2.6/autogen.sh 2014-03-17 16:09:30.000000000 +0000 @@ -5,6 +5,7 @@ test -z "$srcdir" && srcdir=. DIE=0 +ACLOCAL_FLAGS="-I m4" (test -f $srcdir/configure.ac) || { echo -n "**Error**: Directory $srcdir does not look like the" diff -Nru lcms2-2.5/ChangeLog lcms2-2.6/ChangeLog --- lcms2-2.5/ChangeLog 2013-06-27 16:01:28.000000000 +0000 +++ lcms2-2.6/ChangeLog 2014-03-17 16:09:30.000000000 +0000 @@ -125,3 +125,19 @@ ----------------------- 2.5 Maintenance release ----------------------- + +Fixed a double free in recovering from a previous error in default intent handler. +Fixed some indexing out of bounds in floating point interpolation +Fixed a bug in PCS/Colorspace order when reading V2 Lab devicelinks +Added a way to retrieve matrix shaper always, no matter LUT is present +Changed endianess detection for PowerPC +Fixed memory leaks on error handling +Big revamp on Contexts, from Artifex +New locking plug-in, from Artifex +Added directories for tiff, jpeg in configure script +Fix for delete tag memory corruption +Added pthread dependency. From now lcms supports multithreading + +----------------------- +2.6 Featured release +----------------------- diff -Nru lcms2-2.5/configure lcms2-2.6/configure --- lcms2-2.5/configure 2013-06-27 16:01:28.000000000 +0000 +++ lcms2-2.6/configure 2014-03-17 16:09:30.000000000 +0000 @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for lcms2 2.5. +# Generated by GNU Autoconf 2.69 for lcms2 2.6. # # # Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. @@ -587,8 +587,8 @@ # Identity of this package. PACKAGE_NAME='lcms2' PACKAGE_TARNAME='lcms2' -PACKAGE_VERSION='2.5' -PACKAGE_STRING='lcms2 2.5' +PACKAGE_VERSION='2.6' +PACKAGE_STRING='lcms2 2.6' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -644,7 +644,13 @@ LIB_JPEG HasJPEG_FALSE HasJPEG_TRUE +LIB_THREAD LIB_MATH +PTHREAD_CFLAGS +PTHREAD_LIBS +PTHREAD_CXX +PTHREAD_CC +acx_pthread_config inline MAINT MAINTAINER_MODE_FALSE @@ -772,9 +778,6 @@ ac_subst_files='' ac_user_opts=' enable_option_checking -with_jpeg -with_tiff -with_zlib enable_dependency_tracking enable_shared enable_static @@ -784,6 +787,10 @@ with_sysroot enable_libtool_lock enable_maintainer_mode +with_jpeg +with_tiff +with_zlib +with_threads ' ac_precious_vars='build_alias host_alias @@ -1338,7 +1345,7 @@ # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures lcms2 2.5 to adapt to many kinds of systems. +\`configure' configures lcms2 2.6 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1408,7 +1415,7 @@ if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of lcms2 2.5:";; + short | recursive ) echo "Configuration of lcms2 2.6:";; esac cat <<\_ACEOF @@ -1429,14 +1436,15 @@ Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) - --without-jpeg disable JPEG support - --without-tiff disable TIFF support - --without-zlib disable ZLIB support --with-pic try to use only PIC/non-PIC objects [default=use both] --with-gnu-ld assume the C compiler uses GNU ld [default=no] --with-sysroot=DIR Search for dependent libraries within DIR (or the compiler's sysroot if not specified). + --with-jpeg=DIR use jpeg installed in DIR + --with-tiff=DIR use tiff installed in DIR + --without-zlib disable ZLIB support + --without-threads disable POSIX threads API support Some influential environment variables: CC C compiler command @@ -1517,7 +1525,7 @@ test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -lcms2 configure 2.5 +lcms2 configure 2.6 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -2003,7 +2011,7 @@ This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by lcms2 $as_me 2.5, which was +It was created by lcms2 $as_me 2.6, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -2352,6 +2360,9 @@ +# Specify directory where m4 macros may be found. + + # # Libtool library revision control info # See the libtool documentation under the heading "Libtool's versioning @@ -2374,7 +2385,7 @@ # then set age to 0. # LIBRARY_CURRENT=2 -LIBRARY_REVISION=5 +LIBRARY_REVISION=6 LIBRARY_AGE=0 @@ -2918,7 +2929,7 @@ # Define the identity of the package. PACKAGE='lcms2' - VERSION='2.5' + VERSION='2.6' # Some tools Automake needs. @@ -2950,35 +2961,6 @@ -# Disable JPEG. - -# Check whether --with-jpeg was given. -if test "${with_jpeg+set}" = set; then : - withval=$with_jpeg; with_jpeg=$withval -else - with_jpeg='yes' -fi - - -# Disable TIFF. - -# Check whether --with-tiff was given. -if test "${with_tiff+set}" = set; then : - withval=$with_tiff; with_tiff=$withval -else - with_tiff='yes' -fi - - -# Disable ZLIB - -# Check whether --with-zlib was given. -if test "${with_zlib+set}" = set; then : - withval=$with_zlib; with_zlib=$withval -else - with_zlib='yes' -fi - # Check for programs DEPDIR="${am__leading_dot}deps" @@ -15907,6 +15889,542 @@ esac +# Point to JPEG installed in DIR or disable JPEG with --without-jpeg. + +# Check whether --with-jpeg was given. +if test "${with_jpeg+set}" = set; then : + withval=$with_jpeg; + if test "x$withval" = "xno" ; then + with_jpeg='no' + else + if test "x$withval" != "xyes" ; then + with_jpeg=$withval + JPEG_DIR=$withval + CPPFLAGS="$CPPFLAGS -I$JPEG_DIR/include" + LDFLAGS="$LDFLAGS -L$JPEG_DIR/lib" + fi + with_jpeg='yes' + fi + +else + with_jpeg='yes' +fi + + +# Point to TIFF installed in DIR or disable TIFF with --without-tiff. + +# Check whether --with-tiff was given. +if test "${with_tiff+set}" = set; then : + withval=$with_tiff; + if test "x$withval" = "xno" ; then + with_tiff='no' + else + if test "x$withval" != "xyes" ; then + with_tiff=$withval + TIFF_DIR=$withval + CPPFLAGS="$CPPFLAGS -I$TIFF_DIR/include" + LDFLAGS="$LDFLAGS -L$TIFF_DIR/lib" + fi + with_tiff='yes' + fi + +else + with_tiff='yes' +fi + + +# Disable ZLIB + +# Check whether --with-zlib was given. +if test "${with_zlib+set}" = set; then : + withval=$with_zlib; with_zlib=$withval +else + with_zlib='yes' +fi + + +# +# Determine POSIX threads settings +# +# Enable support for POSIX thread APIs + +# Check whether --with-threads was given. +if test "${with_threads+set}" = set; then : + withval=$with_threads; with_threads=$withval +else + with_threads='yes' +fi + + +have_threads=no +if test "$with_threads" != 'no' +then + + + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +acx_pthread_ok=no + +# We used to check for pthread.h first, but this fails if pthread.h +# requires special compiler flags (e.g. on True64 or Sequent). +# It gets checked for in the link test anyway. + +# First of all, check if the user has set any of the PTHREAD_LIBS, +# etcetera environment variables, and if threads linking works using +# them: +if test x"$PTHREAD_LIBS$PTHREAD_CFLAGS" != x; then + save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" + save_LIBS="$LIBS" + LIBS="$PTHREAD_LIBS $LIBS" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS" >&5 +$as_echo_n "checking for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS... " >&6; } + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char pthread_join (); +int +main () +{ +return pthread_join (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + acx_pthread_ok=yes +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $acx_pthread_ok" >&5 +$as_echo "$acx_pthread_ok" >&6; } + if test x"$acx_pthread_ok" = xno; then + PTHREAD_LIBS="" + PTHREAD_CFLAGS="" + fi + LIBS="$save_LIBS" + CFLAGS="$save_CFLAGS" +fi + +# We must check for the threads library under a number of different +# names; the ordering is very important because some systems +# (e.g. DEC) have both -lpthread and -lpthreads, where one of the +# libraries is broken (non-POSIX). + +# Create a list of thread flags to try. Items starting with a "-" are +# C compiler flags, and other items are library names, except for "none" +# which indicates that we try without any flags at all, and "pthread-config" +# which is a program returning the flags for the Pth emulation library. + +acx_pthread_flags="pthreads none -Kthread -kthread lthread -pthread -pthreads -mthreads pthread --thread-safe -mt lpthread pthread-config" + +# The ordering *is* (sometimes) important. Some notes on the +# individual items follow: + +# pthreads: AIX (must check this before -lpthread) +# none: in case threads are in libc; should be tried before -Kthread and +# other compiler flags to prevent continual compiler warnings +# -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h) +# -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able) +# lthread: LinuxThreads port on FreeBSD (also preferred to -pthread) +# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads) +# -pthreads: Solaris/gcc +# -mthreads: Mingw32/gcc, Lynx/gcc +# -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it +# doesn't hurt to check since this sometimes defines pthreads too; +# also defines -D_REENTRANT) +# ... -mt is also the pthreads flag for HP/aCC +# pthread: Linux, etcetera +# --thread-safe: KAI C++ +# pthread-config: use pthread-config program (for GNU Pth library) + +case "${host_cpu}-${host_os}" in + *solaris*) + + # On Solaris (at least, for some versions), libc contains stubbed + # (non-functional) versions of the pthreads routines, so link-based + # tests will erroneously succeed. (We need to link with -pthreads/-mt/ + # -lpthread.) (The stubs are missing pthread_cleanup_push, or rather + # a function called by this macro, so we could check for that, but + # who knows whether they'll stub that too in a future libc.) So, + # we'll just look for -pthreads and -lpthread first: + + acx_pthread_flags="-pthreads pthread -mt -pthread $acx_pthread_flags" + ;; + + # The HP-UX compiler just warns about options it does not understand + # but it needs -mt. + *-hpux*) + acx_pthread_flags="-mt $acx_pthread_flags" + ;; +esac + +if test x"$acx_pthread_ok" = xno; then +for flag in $acx_pthread_flags; do + + case $flag in + none) + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether pthreads work without any flags" >&5 +$as_echo_n "checking whether pthreads work without any flags... " >&6; } + ;; + + -*) + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether pthreads work with $flag" >&5 +$as_echo_n "checking whether pthreads work with $flag... " >&6; } + PTHREAD_CFLAGS="$flag" + ;; + + pthread-config) + # Extract the first word of "pthread-config", so it can be a program name with args. +set dummy pthread-config; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_acx_pthread_config+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$acx_pthread_config"; then + ac_cv_prog_acx_pthread_config="$acx_pthread_config" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_acx_pthread_config="yes" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + test -z "$ac_cv_prog_acx_pthread_config" && ac_cv_prog_acx_pthread_config="no" +fi +fi +acx_pthread_config=$ac_cv_prog_acx_pthread_config +if test -n "$acx_pthread_config"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $acx_pthread_config" >&5 +$as_echo "$acx_pthread_config" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + if test x"$acx_pthread_config" = xno; then continue; fi + PTHREAD_CFLAGS="`pthread-config --cflags`" + PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`" + ;; + + *) + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for the pthreads library -l$flag" >&5 +$as_echo_n "checking for the pthreads library -l$flag... " >&6; } + PTHREAD_LIBS="-l$flag" + ;; + esac + + save_LIBS="$LIBS" + save_CFLAGS="$CFLAGS" + LIBS="$PTHREAD_LIBS $LIBS" + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" + + # Check for various functions. We must include pthread.h, + # since some functions may be macros. (On the Sequent, we + # need a special flag -Kthread to make this header compile.) + # We check for pthread_join because it is in -lpthread on IRIX + # while pthread_create is in libc. We check for pthread_attr_init + # due to DEC craziness with -lpthreads. We check for + # pthread_cleanup_push because it is one of the few pthread + # functions on Solaris that doesn't have a non-functional libc stub. + # We try pthread_create on general principles. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main () +{ +pthread_t th; pthread_join(th, 0); + pthread_attr_init(0); pthread_cleanup_push(0, 0); + pthread_create(0,0,0,0); pthread_cleanup_pop(0); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + acx_pthread_ok=yes +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + + LIBS="$save_LIBS" + CFLAGS="$save_CFLAGS" + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $acx_pthread_ok" >&5 +$as_echo "$acx_pthread_ok" >&6; } + if test "x$acx_pthread_ok" = xyes; then + break; + fi + + PTHREAD_LIBS="" + PTHREAD_CFLAGS="" +done +fi + +# Various other checks: +if test "x$acx_pthread_ok" = xyes; then + save_LIBS="$LIBS" + LIBS="$PTHREAD_LIBS $LIBS" + save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" + + # Detect AIX lossage: JOINABLE attribute is called UNDETACHED. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for joinable pthread attribute" >&5 +$as_echo_n "checking for joinable pthread attribute... " >&6; } + attr_name=unknown + for attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main () +{ +int attr=$attr; return attr; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + attr_name=$attr; break +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + done + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $attr_name" >&5 +$as_echo "$attr_name" >&6; } + if test "$attr_name" != PTHREAD_CREATE_JOINABLE; then + +cat >>confdefs.h <<_ACEOF +#define PTHREAD_CREATE_JOINABLE $attr_name +_ACEOF + + fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if more special flags are required for pthreads" >&5 +$as_echo_n "checking if more special flags are required for pthreads... " >&6; } + flag=no + case "${host_cpu}-${host_os}" in + *-aix* | *-freebsd* | *-darwin*) flag="-D_THREAD_SAFE";; + *solaris* | *-osf* | *-hpux*) flag="-D_REENTRANT";; + esac + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${flag}" >&5 +$as_echo "${flag}" >&6; } + if test "x$flag" != xno; then + PTHREAD_CFLAGS="$flag $PTHREAD_CFLAGS" + fi + + LIBS="$save_LIBS" + CFLAGS="$save_CFLAGS" + + # More AIX lossage: must compile with xlc_r or cc_r + case "${host_os}" in + aix* ) + if test x"$GCC" != xyes; then + case "$CC" in + *xlc ) + # Extract the first word of "xlc_r", so it can be a program name with args. +set dummy xlc_r; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_PTHREAD_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$PTHREAD_CC"; then + ac_cv_prog_PTHREAD_CC="$PTHREAD_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_PTHREAD_CC="xlc_r" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + test -z "$ac_cv_prog_PTHREAD_CC" && ac_cv_prog_PTHREAD_CC="${CC}" +fi +fi +PTHREAD_CC=$ac_cv_prog_PTHREAD_CC +if test -n "$PTHREAD_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PTHREAD_CC" >&5 +$as_echo "$PTHREAD_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + ;; + *cc ) + # Extract the first word of "cc_r", so it can be a program name with args. +set dummy cc_r; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_PTHREAD_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$PTHREAD_CC"; then + ac_cv_prog_PTHREAD_CC="$PTHREAD_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_PTHREAD_CC="cc_r" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + test -z "$ac_cv_prog_PTHREAD_CC" && ac_cv_prog_PTHREAD_CC="${CC}" +fi +fi +PTHREAD_CC=$ac_cv_prog_PTHREAD_CC +if test -n "$PTHREAD_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PTHREAD_CC" >&5 +$as_echo "$PTHREAD_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + ;; + esac + fi + case "$CXX" in + *xlC ) + # Extract the first word of "xlC_r", so it can be a program name with args. +set dummy xlC_r; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_PTHREAD_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$PTHREAD_CXX"; then + ac_cv_prog_PTHREAD_CXX="$PTHREAD_CXX" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_PTHREAD_CXX="xlC_r" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + test -z "$ac_cv_prog_PTHREAD_CXX" && ac_cv_prog_PTHREAD_CXX="${CXX}" +fi +fi +PTHREAD_CXX=$ac_cv_prog_PTHREAD_CXX +if test -n "$PTHREAD_CXX"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PTHREAD_CXX" >&5 +$as_echo "$PTHREAD_CXX" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + ;; + esac + ;; + esac +fi + +if test "${PTHREAD_CC}x" = "x" +then + PTHREAD_CC="$CC" +fi +if test "${PTHREAD_CXX}x" = "x" +then + PTHREAD_CXX="$CXX" +fi + + + + + + +# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND: +if test x"$acx_pthread_ok" = xyes; then + +$as_echo "#define HAVE_PTHREAD 1" >>confdefs.h + + : +else + acx_pthread_ok=no + +fi +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + + if test "$acx_pthread_ok" = yes + then + have_threads=yes + + DEF_THREAD="$PTHREAD_CFLAGS" + CFLAGS="$CFLAGS $DEF_THREAD" + CXXFLAGS="$CXXFLAGS $DEF_THREAD" + + if test "$CC" != "$PTHREAD_CC" + then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Replacing compiler $CC with compiler $PTHREAD_CC to support pthreads." >&5 +$as_echo "$as_me: WARNING: Replacing compiler $CC with compiler $PTHREAD_CC to support pthreads." >&2;} + CC="$PTHREAD_CC" + fi + if test "$CXX" != "$PTHREAD_CXX" + then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Replacing compiler $CXX with compiler $PTHREAD_CXX to support pthreads." >&5 +$as_echo "$as_me: WARNING: Replacing compiler $CXX with compiler $PTHREAD_CXX to support pthreads." >&2;} + CXX="$PTHREAD_CXX" + fi + fi +fi + + # # Find math library # @@ -15955,14 +16473,80 @@ # +# Find Posix threads library +# +LIB_THREAD='' +if test "$with_threads" != 'no' && test "$have_threads" = 'yes' +then + for lib in pthread pthreads + do + if test "x$PTHREAD_LIBS" = "x" ; then + as_ac_Lib=`$as_echo "ac_cv_lib_$lib''_pthread_mutex_lock" | $as_tr_sh` +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_mutex_lock in -l$lib" >&5 +$as_echo_n "checking for pthread_mutex_lock in -l$lib... " >&6; } +if eval \${$as_ac_Lib+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-l$lib $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char pthread_mutex_lock (); +int +main () +{ +return pthread_mutex_lock (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + eval "$as_ac_Lib=yes" +else + eval "$as_ac_Lib=no" +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +eval ac_res=\$$as_ac_Lib + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then : + PTHREAD_LIBS=-l$lib +fi + + fi + done + + LIB_THREAD="$PTHREAD_LIBS" + LIBS="$LIBS $LIB_THREAD" + +$as_echo "#define HasTHREADS 1" >>confdefs.h + +else + +$as_echo "#define HasTHREADS 0" >>confdefs.h + +fi + + +# # Check for JPEG # have_jpeg='no' LIB_JPEG='' if test ! "$with_jpeg" = 'no' then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for JPEG support " >&5 -$as_echo_n "checking for JPEG support ... " >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for JPEG support" >&5 +$as_echo_n "checking for JPEG support... " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: " >&5 $as_echo "" >&6; } failed=0; @@ -16443,8 +17027,8 @@ LIB_TIFF='' if test ! "$with_tiff" = 'no' then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for TIFF support " >&5 -$as_echo_n "checking for TIFF support ... " >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for TIFF support" >&5 +$as_echo_n "checking for TIFF support... " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: " >&5 $as_echo "" >&6; } failed=0; @@ -16637,18 +17221,19 @@ + # Libraries that the LCMS library depends on -LCMS_LIB_DEPLIBS="$LIB_MATH" +LCMS_LIB_DEPLIBS="$LIB_MATH $LIB_THREAD" LCMS_LIB_DEPLIBS=`echo $LCMS_LIB_DEPLIBS | sed -e 's/ */ /g'` # Libraries that the jpegicc program depends on -JPEGICC_DEPLIBS="$LIB_JPEG $LIB_MATH" +JPEGICC_DEPLIBS="$LIB_JPEG $LIB_MATH $LIB_THREAD" JPEGICC_DEPLIBS=`echo $JPEGICC_DEPLIBS | sed -e 's/ */ /g'` # Libraries that the tifficc program depends on -TIFFICC_DEPLIBS="$LIB_TIFF $LIB_JPEG $LIB_ZLIB $LIB_MATH" +TIFFICC_DEPLIBS="$LIB_TIFF $LIB_JPEG $LIB_ZLIB $LIB_MATH $LIB_THREAD" TIFFICC_DEPLIBS=`echo $TIFFICC_DEPLIBS | sed -e 's/ */ /g'` @@ -17256,7 +17841,7 @@ # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by lcms2 $as_me 2.5, which was +This file was extended by lcms2 $as_me 2.6, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -17313,7 +17898,7 @@ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -lcms2 config.status 2.5 +lcms2 config.status 2.6 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" diff -Nru lcms2-2.5/configure.ac lcms2-2.6/configure.ac --- lcms2-2.5/configure.ac 2013-06-27 16:01:28.000000000 +0000 +++ lcms2-2.6/configure.ac 2014-03-17 16:09:30.000000000 +0000 @@ -7,7 +7,10 @@ # # Set the package name and version # -AC_INIT(lcms2,2.5) +AC_INIT(lcms2,2.6) + +# Specify directory where m4 macros may be found. +AC_CONFIG_MACRO_DIR([m4]) # # Libtool library revision control info @@ -31,7 +34,7 @@ # then set age to 0. # LIBRARY_CURRENT=2 -LIBRARY_REVISION=5 +LIBRARY_REVISION=6 LIBRARY_AGE=0 AC_SUBST(LIBRARY_CURRENT)dnl @@ -43,23 +46,6 @@ AM_INIT_AUTOMAKE([foreign 1.7.2 no-define dist-zip]) -# Disable JPEG. -AC_ARG_WITH(jpeg, - [ --without-jpeg disable JPEG support], - [with_jpeg=$withval], - [with_jpeg='yes']) - -# Disable TIFF. -AC_ARG_WITH(tiff, - [ --without-tiff disable TIFF support], - [with_tiff=$withval], - [with_tiff='yes']) - -# Disable ZLIB -AC_ARG_WITH(zlib, - [ --without-zlib disable ZLIB support], - [with_zlib=$withval], - [with_zlib='yes']) # Check for programs AC_PROG_CC_STDC @@ -101,6 +87,86 @@ # Motorola and SPARC CPUs), define `WORDS_BIGENDIAN'. AC_C_BIGENDIAN +# Point to JPEG installed in DIR or disable JPEG with --without-jpeg. +AC_ARG_WITH(jpeg, + [ --with-jpeg=DIR use jpeg installed in DIR], + [ + if [ test "x$withval" = "xno" ]; then + [with_jpeg='no'] + else + if [ test "x$withval" != "xyes" ]; then + with_jpeg=$withval + JPEG_DIR=$withval + CPPFLAGS="$CPPFLAGS -I$JPEG_DIR/include" + LDFLAGS="$LDFLAGS -L$JPEG_DIR/lib" + fi + [with_jpeg='yes'] + fi + ], + [with_jpeg='yes']) + +# Point to TIFF installed in DIR or disable TIFF with --without-tiff. +AC_ARG_WITH(tiff, + [ --with-tiff=DIR use tiff installed in DIR], + [ + if [ test "x$withval" = "xno" ]; then + [with_tiff='no'] + else + if [ test "x$withval" != "xyes" ]; then + with_tiff=$withval + TIFF_DIR=$withval + CPPFLAGS="$CPPFLAGS -I$TIFF_DIR/include" + LDFLAGS="$LDFLAGS -L$TIFF_DIR/lib" + fi + [with_tiff='yes'] + fi + ], + [with_tiff='yes']) + +# Disable ZLIB +AC_ARG_WITH(zlib, + [ --without-zlib disable ZLIB support], + [with_zlib=$withval], + [with_zlib='yes']) + +# +# Determine POSIX threads settings +# +# Enable support for POSIX thread APIs +AC_ARG_WITH(threads, + AS_HELP_STRING([--without-threads], + [disable POSIX threads API support]), + [with_threads=$withval], + [with_threads='yes']) + +have_threads=no +if test "$with_threads" != 'no' +then + + ACX_PTHREAD() + + if test "$acx_pthread_ok" = yes + then + have_threads=yes + + DEF_THREAD="$PTHREAD_CFLAGS" + CFLAGS="$CFLAGS $DEF_THREAD" + CXXFLAGS="$CXXFLAGS $DEF_THREAD" + + if test "$CC" != "$PTHREAD_CC" + then + AC_MSG_WARN([Replacing compiler $CC with compiler $PTHREAD_CC to support pthreads.]) + CC="$PTHREAD_CC" + fi + if test "$CXX" != "$PTHREAD_CXX" + then + AC_MSG_WARN([Replacing compiler $CXX with compiler $PTHREAD_CXX to support pthreads.]) + CXX="$PTHREAD_CXX" + fi + fi +fi + + # # Find math library # @@ -110,13 +176,34 @@ AC_SUBST(LIB_MATH) # +# Find Posix threads library +# +LIB_THREAD='' +if test "$with_threads" != 'no' && test "$have_threads" = 'yes' +then + for lib in pthread pthreads + do + if test "x$PTHREAD_LIBS" = "x" ; then + AC_CHECK_LIB([$lib],pthread_mutex_lock,[PTHREAD_LIBS=-l$lib],,) + fi + done + + LIB_THREAD="$PTHREAD_LIBS" + LIBS="$LIBS $LIB_THREAD" + AC_DEFINE(HasTHREADS,1,[Define if you have pthreads library]) +else + AC_DEFINE(HasTHREADS,0,[Define if you dont have pthreads library]) +fi +AC_SUBST(LIB_THREAD) + +# # Check for JPEG # have_jpeg='no' LIB_JPEG='' if test ! "$with_jpeg" = 'no' then - AC_MSG_CHECKING(for JPEG support ) + AC_MSG_CHECKING([for JPEG support]) AC_MSG_RESULT() failed=0; passed=0; @@ -221,7 +308,7 @@ LIB_TIFF='' if test ! "$with_tiff" = 'no' then - AC_MSG_CHECKING(for TIFF support ) + AC_MSG_CHECKING([for TIFF support]) AC_MSG_RESULT() failed=0; passed=0; @@ -252,18 +339,19 @@ AM_CONDITIONAL(HasTIFF, test "$have_tiff" = 'yes') AC_SUBST(LIB_TIFF) + # Libraries that the LCMS library depends on -LCMS_LIB_DEPLIBS="$LIB_MATH" +LCMS_LIB_DEPLIBS="$LIB_MATH $LIB_THREAD" LCMS_LIB_DEPLIBS=`echo $LCMS_LIB_DEPLIBS | sed -e 's/ */ /g'` AC_SUBST(LCMS_LIB_DEPLIBS) # Libraries that the jpegicc program depends on -JPEGICC_DEPLIBS="$LIB_JPEG $LIB_MATH" +JPEGICC_DEPLIBS="$LIB_JPEG $LIB_MATH $LIB_THREAD" JPEGICC_DEPLIBS=`echo $JPEGICC_DEPLIBS | sed -e 's/ */ /g'` AC_SUBST(JPEGICC_DEPLIBS) # Libraries that the tifficc program depends on -TIFFICC_DEPLIBS="$LIB_TIFF $LIB_JPEG $LIB_ZLIB $LIB_MATH" +TIFFICC_DEPLIBS="$LIB_TIFF $LIB_JPEG $LIB_ZLIB $LIB_MATH $LIB_THREAD" TIFFICC_DEPLIBS=`echo $TIFFICC_DEPLIBS | sed -e 's/ */ /g'` AC_SUBST(TIFFICC_DEPLIBS) diff -Nru lcms2-2.5/debian/changelog lcms2-2.6/debian/changelog --- lcms2-2.5/debian/changelog 2014-01-16 05:45:59.000000000 +0000 +++ lcms2-2.6/debian/changelog 2014-10-26 04:21:54.000000000 +0000 @@ -1,69 +1,103 @@ -lcms2 (2.5-0ubuntu4) trusty; urgency=low +lcms2 (2.6-3ubuntu1~trusty) trusty; urgency=medium - * fix-floating-point-rounding-in-version-numbers.diff: Fix roundtripping of - version header field; writing 2.30 in the version field would read as 2.29. - Fixes the colord autopkgtests. Yay! + * For trusty - -- Christopher James Halse Rogers Thu, 16 Jan 2014 16:45:47 +1100 + -- Doug McMahon Sun, 26 Oct 2014 00:21:28 -0400 -lcms2 (2.5-0ubuntu3) trusty; urgency=low +lcms2 (2.6-3ubuntu1) utopic; urgency=low - * Remove bizarre and unnecessary clean target and use dh_autotools_dev. - * byte-order.patch: Replace arch-specific tests with __BYTE_ORDER test. + * Merge with Debian, remaining change: + - debian/patches/byte-order.patch: Use endian.h to determine byte order in + use. - -- Adam Conrad Wed, 11 Dec 2013 04:13:40 -0700 + -- Iain Lane Mon, 23 Jun 2014 10:32:56 +0100 -lcms2 (2.5-0ubuntu2) trusty; urgency=low +lcms2 (2.6-3) unstable; urgency=medium - * powerpc64le.patch: patch aclocal.m4 for ppc64el and regen configure. + * New patch: endianness-verification-fix-powerpc.patch. + Thanks to "Fernando Seiti Furusato" + (Closes: #750686) - -- Adam Conrad Wed, 11 Dec 2013 03:36:06 -0700 + -- Thomas Weber Mon, 16 Jun 2014 17:14:13 +0200 -lcms2 (2.5-0ubuntu1) saucy; urgency=low +lcms2 (2.6-2) unstable; urgency=medium - * New upstream version (fixes various crashes that could be used by - attackers to crash (NULL ptr deref) programs using lcms2. - * Update config.{gues,sub} for Aarch64. - * Update symbols file. + * New patch: fix-unaligned-access.patch: Align access to double values. + Thanks to Aurelien Jarno (Closes: #749975) - -- Matthias Klose Tue, 23 Jul 2013 21:39:38 +0200 + -- Thomas Weber Thu, 05 Jun 2014 14:51:56 +0000 -lcms2 (2.4-0ubuntu3) raring; urgency=low +lcms2 (2.6-1ubuntu1) utopic; urgency=medium - * Drop fix-threading-issue-in-plugin-registration.patch. This was added for - GhostScript 9.07, but gs 9.07 segfaults with only this patch; they need - more patches from their lcms2 fork. It seems sensible at this point to wait - until they've upstreamed their fork, rather than trying to pick bits out of - it or adopt the fork wholesale. + * Rebase on Debian, remaining change: + - debian/patches/byte-order.patch: Use endian.h to determine byte order in + use. - -- Christopher James Halse Rogers Fri, 15 Mar 2013 18:50:41 +1100 + -- Iain Lane Thu, 05 Jun 2014 16:42:44 +0100 -lcms2 (2.4-0ubuntu2) raring; urgency=low +lcms2 (2.6-1) unstable; urgency=medium - * debian/patches/fix-threading-issue-in-plugin-registration.patch: - - Provide a thread-safe way for plugins to register; needed for new - ghostscript 9.07 (LP: #1126427) + * Imported Upstream version 2.6 + + Drop patch fix-memory-write-bug.patch (applied upstream) + + Update symbols file for 2.6 release + * Include up-to-date source files for documentation + * Remove quilt from Build-Depends: + Thanks to Mathieu Malaterre (Closes: #741435) + * Update package description + * Update manpages (Closes: #742587) + * Update libtool by using dh-autoreconf. + Thanks to "Breno Leitao" (Closes: 745748) + * new patch: prepare-for-libtoolizing.patch, needed for libtool update + * Sanity check profile versions (CVE-2014-0459) (Closes: #745471) - -- Christopher James Halse Rogers Wed, 13 Mar 2013 12:13:21 +1100 + -- Thomas Weber Fri, 25 Apr 2014 14:53:42 +0200 -lcms2 (2.4-0ubuntu1) raring; urgency=low +lcms2 (2.5-1) unstable; urgency=low - * New upstream release - - Update debian/liblcms2-2.symbols - - Add new symbols for 2.4 - - Drop lost symbol cmsGetStockOutputFormatter after verifying it is not - used in any packaged reverse build-depends - - Corrected previous symbol entries to not inclue package revision + * Imported Upstream version 2.5 (Closes: #701993, #701971) + * Dropped patches (applied upstream): + - sparc64-ftbfs + - ojdk-8007925+8007926.patch + - ojdk-8009654.patch + - ojdk-8007929.patch + - ojdk-8007927.patch + * Refresh patch fix-cmsnamed-alignment-issue.patch + * Bump debhelper level to 9 + * Bump Standards version to 3.9.5, no changes needed + * Update Debian copyright + * Always update config.sub and config.guess. + Thanks to Wookey (Closes: #717839) + * Add debug package + * Add symbols file from Ubuntu + * Update and activate VCS fields in debian/control (Closes: #639607) + * Add Thomas Weber as uploader/co-maintainer + * New patch: fix-memory-write-bug.patch (LP: 1261840) - -- Scott Kitterman Thu, 29 Nov 2012 16:24:47 -0500 + -- Thomas Weber Sun, 09 Feb 2014 02:21:26 +0100 -lcms2 (2.2+git20110628-2.2ubuntu1) raring; urgency=low +lcms2 (2.2+git20110628-2.3) unstable; urgency=low - * Merge from Debian unstable. Remaining changes: - - debian/control: Use unversioned libtiff-dev instead of libtiff4-dev - - debian/liblcms2-2.symbols: Add symbols file for the shared library + * Non-maintainer upload. + * debian/patches/sparc64-ftbfs: align blocks according to host + requirements. Thanks to Aurelien Jarno . + Closes: #647220. + * debian/patches/fix-cmsnamed-alignment-issue.patch: fix alignment + issues when casting chars to shorts. Thanks to Michael Cree + . Closes: #644473. + * Apply security fixes from IcedTea (Closes: #714529, CVE-2013-4160): + - debian/patches/ojdk-8007925+8007926.patch: Improve + cmsStageAllocLabV2ToV4curves. Improve cmsPipelineDup. + - debian/patches/ojdk-8007927.patch: Improve + cmsAllocProfileSequenceDescription. + - debian/patches/ojdk-8007929.patch: Improve CurvesAlloc. + - debian/patches/ojdk-8009654.patch: Improve stability of cmsnamed. + * Build-depend on libtiff-dev instead of libtiff4-dev, to facilitate future + library transitions. Thanks to Michael Terry + for the patch. Closes: #681904. + * Fix a typo in the liblcms2-utils package description. Thanks to + Paolo Scarabelli . Closes: #640084. - -- Michael Terry Sat, 17 Nov 2012 11:24:34 -0500 + -- Steve Langasek Sun, 06 Oct 2013 12:38:01 -0700 lcms2 (2.2+git20110628-2.2) unstable; urgency=low @@ -84,32 +118,6 @@ -- gregor herrmann Tue, 06 Mar 2012 18:46:04 +0100 -lcms2 (2.2+git20110628-2ubuntu4) quantal; urgency=low - - * debian/control: - - Use unversioned libtiff-dev instead of libtiff4-dev - - -- Michael Terry Tue, 17 Jul 2012 11:49:39 -0400 - -lcms2 (2.2+git20110628-2ubuntu3) precise; urgency=low - - * Rebuild for libjpeg8. - - -- Colin Watson Tue, 18 Oct 2011 17:22:44 +0100 - -lcms2 (2.2+git20110628-2ubuntu2) oneiric; urgency=low - - * Convert library packages to multiarch. LP: #836004. - - -- Matthias Klose Sun, 28 Aug 2011 13:40:38 +0200 - -lcms2 (2.2+git20110628-2ubuntu1) oneiric; urgency=low - - * debian/liblcms2-2.symbols: Added symbols file for the shared library, - generated with "dpkg-gensymbols -pliblcms2-2". - - -- Till Kamppeter Tue, 09 Aug 2011 17:05:31 +0200 - lcms2 (2.2+git20110628-2) unstable; urgency=low * debian/control: @@ -142,4 +150,3 @@ * Initial release (Closes: #590222). -- Oleksandr Moskalenko Sun, 23 Jan 2011 15:26:53 -0600 - diff -Nru lcms2-2.5/debian/compat lcms2-2.6/debian/compat --- lcms2-2.5/debian/compat 2012-11-29 21:24:05.000000000 +0000 +++ lcms2-2.6/debian/compat 2014-06-19 12:01:14.000000000 +0000 @@ -1 +1 @@ -7 +9 diff -Nru lcms2-2.5/debian/control lcms2-2.6/debian/control --- lcms2-2.5/debian/control 2012-11-29 21:24:05.000000000 +0000 +++ lcms2-2.6/debian/control 2014-06-19 12:01:13.000000000 +0000 @@ -3,11 +3,12 @@ Priority: optional Maintainer: Ubuntu Developers XSBC-Original-Maintainer: Oleksandr Moskalenko -Build-Depends: debhelper (>= 9), dpkg-dev (>= 1.16.0), autotools-dev, libjpeg-dev, libtiff-dev, zlib1g-dev, quilt -Standards-Version: 3.9.2 +Uploaders: Thomas Weber +Build-Depends: debhelper (>= 9), dpkg-dev (>= 1.16.0), dh-autoreconf, libjpeg-dev, libtiff-dev, zlib1g-dev +Standards-Version: 3.9.5 Homepage: http://www.littlecms.com/ -#Vcs-Git: git://git.debian.org/collab-maint/liblcms2.git -#Vcs-Browser: http://git.debian.org/?p=collab-maint/liblcms2.git;a=summary +Vcs-Git: git://anonscm.debian.org/collab-maint/lcms2.git +Vcs-Browser: http://anonscm.debian.org/gitweb/?p=collab-maint/lcms2.git Package: liblcms2-dev Section: libdevel @@ -20,8 +21,26 @@ Consortium standard (ICC) of color management. Little CMS 2 is a full implementation of ICC specification 4.2 plus all addendums. It fully supports all V2 and V4 profiles, including abstract, devicelink and named color - profiles. This package contains the development headers used for building - software that uses Little CMS. + profiles. + . + This package contains the development headers used for building software that + uses Little CMS. + +Package: liblcms2-dbg +Section: debug +Priority: extra +Architecture: any +Multi-Arch: same +Depends: liblcms2-2 (= ${binary:Version}), ${misc:Depends} +Description: debugging symbols for lcms2 + LittleCMS 2 intends to be a small-footprint color management engine, with + special focus on accuracy and performance. It uses the International Color + Consortium standard (ICC) of color management. Little CMS 2 is a full + implementation of ICC specification 4.2 plus all addendums. It fully supports + all V2 and V4 profiles, including abstract, devicelink and named color + profiles. + . + This package contains the debugging symbols for liblcms2. Package: liblcms2-2 Section: libs @@ -37,15 +56,21 @@ implementation of ICC specification 4.2 plus all addendums. It fully supports all V2 and V4 profiles, including abstract, devicelink and named color profiles. + . + This package contains the shared library of liblcms2. Package: liblcms2-utils Section: utils Architecture: any +Multi-Arch: foreign Depends: ${shlibs:Depends}, ${misc:Depends} -Description: Little CMS 2 olor management library +Description: Little CMS 2 color management library (utilities) LittleCMS 2 intends to be a small-footprint color management engine, with special focus on accuracy and performance. It uses the International Color Consortium standard (ICC) of color management. LittleCMS 2 is a full implementation of ICC specification 4.2 plus all addendums. It fully supports all V2 and V4 profiles, including abstract, devicelink and named color - profiles. This package contains additional utilities (jpegicc and tifficc). + profiles. + . + This package contains additional utilities (jpegicc, linkicc, psicc, tificc + and transicc). diff -Nru lcms2-2.5/debian/copyright lcms2-2.6/debian/copyright --- lcms2-2.5/debian/copyright 2012-11-29 21:24:05.000000000 +0000 +++ lcms2-2.6/debian/copyright 2014-06-19 12:01:14.000000000 +0000 @@ -1,9 +1,9 @@ -Format: http://dep.debian.net/deps/dep5 +Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ Upstream-Name: Little CMS Source: http://www.littlecms.com/ Files: * -Copyright: 1998-2011 Marti Maria Saguer +Copyright: 1998-2014 Marti Maria Saguer License: MIT Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -25,6 +25,7 @@ Files: debian/* Copyright: 2011 Oleksandr Moskalenko + 2013 Thomas Weber License: GPL-2+ This package is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff -Nru lcms2-2.5/debian/liblcms2-2.symbols lcms2-2.6/debian/liblcms2-2.symbols --- lcms2-2.5/debian/liblcms2-2.symbols 2013-07-23 19:47:48.000000000 +0000 +++ lcms2-2.6/debian/liblcms2-2.symbols 2014-06-19 12:01:13.000000000 +0000 @@ -2,9 +2,25 @@ _cms15Fixed16toDouble@Base 2.2+git20110628 _cms8Fixed8toDouble@Base 2.2+git20110628 _cmsAdaptationMatrix@Base 2.2+git20110628 + _cmsAdaptationStateChunk@Base 2.6 _cmsAdjustEndianess16@Base 2.2+git20110628 _cmsAdjustEndianess32@Base 2.2+git20110628 _cmsAdjustEndianess64@Base 2.2+git20110628 + _cmsAlarmCodesChunk@Base 2.6 + _cmsAllocAdaptationStateChunk@Base 2.6 + _cmsAllocAlarmCodesChunk@Base 2.6 + _cmsAllocCurvesPluginChunk@Base 2.6 + _cmsAllocFormattersPluginChunk@Base 2.6 + _cmsAllocIntentsPluginChunk@Base 2.6 + _cmsAllocInterpPluginChunk@Base 2.6 + _cmsAllocLogErrorChunk@Base 2.6 + _cmsAllocMPETypePluginChunk@Base 2.6 + _cmsAllocMemPluginChunk@Base 2.6 + _cmsAllocMutexPluginChunk@Base 2.6 + _cmsAllocOptimizationPluginChunk@Base 2.6 + _cmsAllocTagPluginChunk@Base 2.6 + _cmsAllocTagTypePluginChunk@Base 2.6 + _cmsAllocTransformPluginChunk@Base 2.6 _cmsBuildKToneCurve@Base 2.2+git20110628 _cmsBuildRGB2XYZtransferMatrix@Base 2.2+git20110628 _cmsCalloc@Base 2.2+git20110628 @@ -12,10 +28,14 @@ _cmsCompileProfileSequence@Base 2.2+git20110628 _cmsComputeInterpParams@Base 2.2+git20110628 _cmsComputeInterpParamsEx@Base 2.2+git20110628 + _cmsContextGetClientChunk@Base 2.6 _cmsCreateGamutCheckPipeline@Base 2.2+git20110628 + _cmsCreateMutex@Base 2.6 _cmsCreateSubAlloc@Base 2.2+git20110628 + _cmsCurvesPluginChunk@Base 2.6 _cmsDecodeDateTimeNumber@Base 2.2+git20110628 _cmsDefaultICCintents@Base 2.2+git20110628 + _cmsDestroyMutex@Base 2.6 _cmsDoubleTo15Fixed16@Base 2.2+git20110628 _cmsDoubleTo8Fixed8@Base 2.2+git20110628 _cmsDupMem@Base 2.2+git20110628 @@ -24,8 +44,10 @@ _cmsFloat2Half@Base 2.4 _cmsFormatterIs8bit@Base 2.2+git20110628 _cmsFormatterIsFloat@Base 2.2+git20110628 + _cmsFormattersPluginChunk@Base 2.6 _cmsFree@Base 2.2+git20110628 _cmsFreeInterpParams@Base 2.2+git20110628 + _cmsGetContext@Base 2.6 _cmsGetFormatter@Base 2.2+git20110628 _cmsGetTagDescriptor@Base 2.2+git20110628 _cmsGetTagTrueType@Base 2.2+git20110628 @@ -36,16 +58,25 @@ _cmsHalf2Float@Base 2.4 _cmsICCcolorSpace@Base 2.2+git20110628 _cmsIOPrintf@Base 2.2+git20110628 + _cmsInstallAllocFunctions@Base 2.6 + _cmsIntentsPluginChunk@Base 2.6 + _cmsInterpPluginChunk@Base 2.6 _cmsLCMScolorSpace@Base 2.2+git20110628 _cmsLinkProfiles@Base 2.2+git20110628 + _cmsLockMutex@Base 2.6 + _cmsLogErrorChunk@Base 2.6 _cmsMAT3eval@Base 2.2+git20110628 _cmsMAT3identity@Base 2.2+git20110628 _cmsMAT3inverse@Base 2.2+git20110628 _cmsMAT3isIdentity@Base 2.2+git20110628 _cmsMAT3per@Base 2.2+git20110628 _cmsMAT3solve@Base 2.2+git20110628 + _cmsMPETypePluginChunk@Base 2.6 _cmsMalloc@Base 2.2+git20110628 _cmsMallocZero@Base 2.2+git20110628 + _cmsMemPluginChunk@Base 2.6 + _cmsMutexPluginChunk@Base 2.6 + _cmsOptimizationPluginChunk@Base 2.6 _cmsOptimizePipeline@Base 2.2+git20110628 _cmsPipelineSetOptimizationParameters@Base 2.2+git20110628 _cmsPluginMalloc@Base 2.2+git20110628 @@ -73,6 +104,7 @@ _cmsRegisterInterpPlugin@Base 2.2+git20110628 _cmsRegisterMemHandlerPlugin@Base 2.2+git20110628 _cmsRegisterMultiProcessElementPlugin@Base 2.2+git20110628 + _cmsRegisterMutexPlugin@Base 2.6 _cmsRegisterOptimizationPlugin@Base 2.2+git20110628 _cmsRegisterParametricCurvesPlugin@Base 2.2+git20110628 _cmsRegisterRenderingIntentPlugin@Base 2.2+git20110628 @@ -99,7 +131,12 @@ _cmsStageNormalizeToXyzFloat@Base 2.4 _cmsSubAlloc@Base 2.2+git20110628 _cmsSubAllocDestroy@Base 2.2+git20110628 + _cmsSubAllocDup@Base 2.6 + _cmsTagPluginChunk@Base 2.6 _cmsTagSignature2String@Base 2.2+git20110628 + _cmsTagTypePluginChunk@Base 2.6 + _cmsTransformPluginChunk@Base 2.6 + _cmsUnlockMutex@Base 2.6 _cmsVEC3cross@Base 2.2+git20110628 _cmsVEC3distance@Base 2.2+git20110628 _cmsVEC3dot@Base 2.2+git20110628 @@ -141,6 +178,7 @@ cmsCloseProfile@Base 2.2+git20110628 cmsCreateBCHSWabstractProfile@Base 2.2+git20110628 cmsCreateBCHSWabstractProfileTHR@Base 2.2+git20110628 + cmsCreateContext@Base 2.6 cmsCreateExtendedTransform@Base 2.2+git20110628 cmsCreateGrayProfile@Base 2.2+git20110628 cmsCreateGrayProfileTHR@Base 2.2+git20110628 @@ -169,6 +207,7 @@ cmsCreate_sRGBProfileTHR@Base 2.2+git20110628 cmsD50_XYZ@Base 2.2+git20110628 cmsD50_xyY@Base 2.2+git20110628 + cmsDeleteContext@Base 2.6 cmsDeleteTransform@Base 2.2+git20110628 cmsDeltaE@Base 2.2+git20110628 cmsDesaturateLab@Base 2.2+git20110628 @@ -183,6 +222,7 @@ cmsDictNextEntry@Base 2.2+git20110628 cmsDoTransform@Base 2.2+git20110628 cmsDoTransformStride@Base 2.4 + cmsDupContext@Base 2.6 cmsDupNamedColorList@Base 2.2+git20110628 cmsDupProfileSequenceDescription@Base 2.2+git20110628 cmsDupToneCurve@Base 2.2+git20110628 @@ -204,7 +244,9 @@ cmsGDBCheckPoint@Base 2.2+git20110628 cmsGDBCompute@Base 2.2+git20110628 cmsGetAlarmCodes@Base 2.2+git20110628 + cmsGetAlarmCodesTHR@Base 2.6 cmsGetColorSpace@Base 2.2+git20110628 + cmsGetContextUserData@Base 2.6 cmsGetDeviceClass@Base 2.2+git20110628 cmsGetEncodedICCversion@Base 2.2+git20110628 cmsGetHeaderAttributes@Base 2.2+git20110628 @@ -226,6 +268,7 @@ cmsGetProfileInfoASCII@Base 2.2+git20110628 cmsGetProfileVersion@Base 2.2+git20110628 cmsGetSupportedIntents@Base 2.2+git20110628 + cmsGetSupportedIntentsTHR@Base 2.6 cmsGetTagCount@Base 2.2+git20110628 cmsGetTagSignature@Base 2.2+git20110628 cmsGetToneCurveEstimatedTable@Base 2.4 @@ -306,6 +349,7 @@ cmsOpenIOhandlerFromStream@Base 2.2+git20110628 cmsOpenProfileFromFile@Base 2.2+git20110628 cmsOpenProfileFromFileTHR@Base 2.2+git20110628 + cmsOpenProfileFromIOhandler2THR@Base 2.6 cmsOpenProfileFromIOhandlerTHR@Base 2.2+git20110628 cmsOpenProfileFromMem@Base 2.2+git20110628 cmsOpenProfileFromMemTHR@Base 2.2+git20110628 @@ -338,7 +382,9 @@ cmsSaveProfileToMem@Base 2.2+git20110628 cmsSaveProfileToStream@Base 2.2+git20110628 cmsSetAdaptationState@Base 2.2+git20110628 + cmsSetAdaptationStateTHR@Base 2.6 cmsSetAlarmCodes@Base 2.2+git20110628 + cmsSetAlarmCodesTHR@Base 2.6 cmsSetColorSpace@Base 2.2+git20110628 cmsSetDeviceClass@Base 2.2+git20110628 cmsSetEncodedICCversion@Base 2.2+git20110628 @@ -349,6 +395,7 @@ cmsSetHeaderProfileID@Base 2.2+git20110628 cmsSetHeaderRenderingIntent@Base 2.2+git20110628 cmsSetLogErrorHandler@Base 2.2+git20110628 + cmsSetLogErrorHandlerTHR@Base 2.6 cmsSetPCS@Base 2.2+git20110628 cmsSetProfileVersion@Base 2.2+git20110628 cmsSignalError@Base 2.2+git20110628 @@ -375,6 +422,7 @@ cmsTempFromWhitePoint@Base 2.2+git20110628 cmsTransform2DeviceLink@Base 2.2+git20110628 cmsUnregisterPlugins@Base 2.2+git20110628 + cmsUnregisterPluginsTHR@Base 2.6 cmsWhitePointFromTemp@Base 2.2+git20110628 cmsWriteRawTag@Base 2.2+git20110628 cmsWriteTag@Base 2.2+git20110628 diff -Nru lcms2-2.5/debian/patches/byte-order.patch lcms2-2.6/debian/patches/byte-order.patch --- lcms2-2.5/debian/patches/byte-order.patch 2013-12-11 11:34:22.000000000 +0000 +++ lcms2-2.6/debian/patches/byte-order.patch 2014-06-23 09:22:18.000000000 +0000 @@ -1,31 +1,51 @@ Description: Replace arch-specific tests with __BYTE_ORDER test. Author: Adam Conrad ---- lcms2-2.5.orig/include/lcms2.h -+++ lcms2-2.5/include/lcms2.h -@@ -173,22 +173,9 @@ typedef int cmsBool; +Index: b/include/lcms2.h +=================================================================== +--- a/include/lcms2.h ++++ b/include/lcms2.h +@@ -176,40 +176,9 @@ // Try to detect big endian platforms. This list can be endless, so only some checks are performed over here. // you can pass this toggle to the compiler by using -DCMS_USE_BIG_ENDIAN or something similar --#if defined(_HOST_BIG_ENDIAN) || defined(__BIG_ENDIAN__) || defined(WORDS_BIGENDIAN) +-#if defined(__sgi__) || defined(__sgi) || defined(sparc) -# define CMS_USE_BIG_ENDIAN 1 -#endif - --#if defined(__sgi__) || defined(__sgi) || defined(__powerpc__) || defined(sparc) --# define CMS_USE_BIG_ENDIAN 1 +-#if defined(__s390__) || defined(__s390x__) +-# define CMS_USE_BIG_ENDIAN 1 -#endif - --#if defined(__ppc__) || defined(__s390__) || defined(__s390x__) +-# ifdef TARGET_CPU_PPC +-# if TARGET_CPU_PPC +-# define CMS_USE_BIG_ENDIAN 1 +-# endif +-# endif +- +-#if defined(__powerpc__) || defined(__ppc__) || defined(TARGET_CPU_PPC) -# define CMS_USE_BIG_ENDIAN 1 +-# if defined (__GNUC__) && defined(__LITTLE_ENDIAN__) +-// // Don't use big endian for PowerPC little endian mode +-# undef CMS_USE_BIG_ENDIAN +-# endif -#endif - --#ifdef TARGET_CPU_PPC --# if TARGET_CPU_PPC --# define CMS_USE_BIG_ENDIAN 1 +-// WORDS_BIGENDIAN takes precedence +-#if defined(_HOST_BIG_ENDIAN) || defined(__BIG_ENDIAN__) || defined(WORDS_BIGENDIAN) +-# define CMS_USE_BIG_ENDIAN 1 +-#endif +- +-#ifdef macintosh +-# ifdef __BIG_ENDIAN__ +-# define CMS_USE_BIG_ENDIAN 1 +-# endif +-# ifdef __LITTLE_ENDIAN__ +-# undef CMS_USE_BIG_ENDIAN -# endif +#include +#if __BYTE_ORDER == __BIG_ENDIAN +# define CMS_USE_BIG_ENDIAN 1 #endif - #ifdef macintosh + // Calling convention -- this is hardly platform and compiler dependent diff -Nru lcms2-2.5/debian/patches/config-updates.diff lcms2-2.6/debian/patches/config-updates.diff --- lcms2-2.5/debian/patches/config-updates.diff 2013-07-23 19:43:19.000000000 +0000 +++ lcms2-2.6/debian/patches/config-updates.diff 1970-01-01 00:00:00.000000000 +0000 @@ -1,1400 +0,0 @@ -Index: b/config.guess -=================================================================== ---- a/config.guess -+++ b/config.guess -@@ -1,14 +1,12 @@ - #! /bin/sh - # Attempt to guess a canonical system name. --# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, --# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 --# Free Software Foundation, Inc. -+# Copyright 1992-2013 Free Software Foundation, Inc. - --timestamp='2009-11-20' -+timestamp='2013-05-16' - - # This file 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 -+# the Free Software Foundation; either version 3 of the License, or - # (at your option) any later version. - # - # This program is distributed in the hope that it will be useful, but -@@ -17,26 +15,22 @@ - # 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., 51 Franklin Street - Fifth Floor, Boston, MA --# 02110-1301, USA. -+# along with this program; if not, see . - # - # As a special exception to the GNU General Public License, if you - # distribute this file as part of a program that contains a - # configuration script generated by Autoconf, you may include it under --# the same distribution terms that you use for the rest of that program. -- -- --# Originally written by Per Bothner. Please send patches (context --# diff format) to and include a ChangeLog --# entry. -+# the same distribution terms that you use for the rest of that -+# program. This Exception is an additional permission under section 7 -+# of the GNU General Public License, version 3 ("GPLv3"). - # --# This script attempts to guess a canonical system name similar to --# config.sub. If it succeeds, it prints the system name on stdout, and --# exits with 0. Otherwise, it exits with 1. -+# Originally written by Per Bothner. - # - # You can get the latest version of this script from: - # http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD -+# -+# Please send patches with a ChangeLog entry to config-patches@gnu.org. -+ - - me=`echo "$0" | sed -e 's,.*/,,'` - -@@ -56,8 +50,7 @@ - GNU config.guess ($timestamp) - - Originally written by Per Bothner. --Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, --2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. -+Copyright 1992-2013 Free Software Foundation, Inc. - - This is free software; see the source for copying conditions. There is NO - warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." -@@ -139,12 +132,33 @@ - UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown - UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown - -+case "${UNAME_SYSTEM}" in -+Linux|GNU|GNU/*) -+ # If the system lacks a compiler, then just pick glibc. -+ # We could probably try harder. -+ LIBC=gnu -+ -+ eval $set_cc_for_build -+ cat <<-EOF > $dummy.c -+ #include -+ #if defined(__UCLIBC__) -+ LIBC=uclibc -+ #elif defined(__dietlibc__) -+ LIBC=dietlibc -+ #else -+ LIBC=gnu -+ #endif -+ EOF -+ eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'` -+ ;; -+esac -+ - # Note: order is significant - the case branches are not exclusive. - - case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in - *:NetBSD:*:*) - # NetBSD (nbsd) targets should (where applicable) match one or -- # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*, -+ # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*, - # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently - # switched to ELF, *-*-netbsd* would select the old - # object file format. This provides both forward -@@ -180,7 +194,7 @@ - fi - ;; - *) -- os=netbsd -+ os=netbsd - ;; - esac - # The OS release -@@ -201,6 +215,10 @@ - # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. - echo "${machine}-${os}${release}" - exit ;; -+ *:Bitrig:*:*) -+ UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'` -+ echo ${UNAME_MACHINE_ARCH}-unknown-bitrig${UNAME_RELEASE} -+ exit ;; - *:OpenBSD:*:*) - UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` - echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} -@@ -223,7 +241,7 @@ - UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` - ;; - *5.*) -- UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` -+ UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` - ;; - esac - # According to Compaq, /usr/sbin/psrinfo has been available on -@@ -269,7 +287,10 @@ - # A Xn.n version is an unreleased experimental baselevel. - # 1.2 uses "1.2" for uname -r. - echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` -- exit ;; -+ # Reset EXIT trap before exiting to avoid spurious non-zero exit code. -+ exitcode=$? -+ trap '' 0 -+ exit $exitcode ;; - Alpha\ *:Windows_NT*:*) - # How do we know it's Interix rather than the generic POSIX subsystem? - # Should we change UNAME_MACHINE based on the output of uname instead -@@ -295,12 +316,12 @@ - echo s390-ibm-zvmoe - exit ;; - *:OS400:*:*) -- echo powerpc-ibm-os400 -+ echo powerpc-ibm-os400 - exit ;; - arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) - echo arm-acorn-riscix${UNAME_RELEASE} - exit ;; -- arm:riscos:*:*|arm:RISCOS:*:*) -+ arm*:riscos:*:*|arm*:RISCOS:*:*) - echo arm-unknown-riscos - exit ;; - SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) -@@ -394,23 +415,23 @@ - # MiNT. But MiNT is downward compatible to TOS, so this should - # be no problem. - atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) -- echo m68k-atari-mint${UNAME_RELEASE} -+ echo m68k-atari-mint${UNAME_RELEASE} - exit ;; - atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} -- exit ;; -+ exit ;; - *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) -- echo m68k-atari-mint${UNAME_RELEASE} -+ echo m68k-atari-mint${UNAME_RELEASE} - exit ;; - milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) -- echo m68k-milan-mint${UNAME_RELEASE} -- exit ;; -+ echo m68k-milan-mint${UNAME_RELEASE} -+ exit ;; - hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) -- echo m68k-hades-mint${UNAME_RELEASE} -- exit ;; -+ echo m68k-hades-mint${UNAME_RELEASE} -+ exit ;; - *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) -- echo m68k-unknown-mint${UNAME_RELEASE} -- exit ;; -+ echo m68k-unknown-mint${UNAME_RELEASE} -+ exit ;; - m68k:machten:*:*) - echo m68k-apple-machten${UNAME_RELEASE} - exit ;; -@@ -480,8 +501,8 @@ - echo m88k-motorola-sysv3 - exit ;; - AViiON:dgux:*:*) -- # DG/UX returns AViiON for all architectures -- UNAME_PROCESSOR=`/usr/bin/uname -p` -+ # DG/UX returns AViiON for all architectures -+ UNAME_PROCESSOR=`/usr/bin/uname -p` - if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] - then - if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ -@@ -494,7 +515,7 @@ - else - echo i586-dg-dgux${UNAME_RELEASE} - fi -- exit ;; -+ exit ;; - M88*:DolphinOS:*:*) # DolphinOS (SVR3) - echo m88k-dolphin-sysv3 - exit ;; -@@ -551,7 +572,7 @@ - echo rs6000-ibm-aix3.2 - fi - exit ;; -- *:AIX:*:[456]) -+ *:AIX:*:[4567]) - IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` - if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then - IBM_ARCH=rs6000 -@@ -594,52 +615,52 @@ - 9000/[678][0-9][0-9]) - if [ -x /usr/bin/getconf ]; then - sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` -- sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` -- case "${sc_cpu_version}" in -- 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 -- 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 -- 532) # CPU_PA_RISC2_0 -- case "${sc_kernel_bits}" in -- 32) HP_ARCH="hppa2.0n" ;; -- 64) HP_ARCH="hppa2.0w" ;; -+ sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` -+ case "${sc_cpu_version}" in -+ 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 -+ 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 -+ 532) # CPU_PA_RISC2_0 -+ case "${sc_kernel_bits}" in -+ 32) HP_ARCH="hppa2.0n" ;; -+ 64) HP_ARCH="hppa2.0w" ;; - '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 -- esac ;; -- esac -+ esac ;; -+ esac - fi - if [ "${HP_ARCH}" = "" ]; then - eval $set_cc_for_build -- sed 's/^ //' << EOF >$dummy.c -+ sed 's/^ //' << EOF >$dummy.c - -- #define _HPUX_SOURCE -- #include -- #include -- -- int main () -- { -- #if defined(_SC_KERNEL_BITS) -- long bits = sysconf(_SC_KERNEL_BITS); -- #endif -- long cpu = sysconf (_SC_CPU_VERSION); -- -- switch (cpu) -- { -- case CPU_PA_RISC1_0: puts ("hppa1.0"); break; -- case CPU_PA_RISC1_1: puts ("hppa1.1"); break; -- case CPU_PA_RISC2_0: -- #if defined(_SC_KERNEL_BITS) -- switch (bits) -- { -- case 64: puts ("hppa2.0w"); break; -- case 32: puts ("hppa2.0n"); break; -- default: puts ("hppa2.0"); break; -- } break; -- #else /* !defined(_SC_KERNEL_BITS) */ -- puts ("hppa2.0"); break; -- #endif -- default: puts ("hppa1.0"); break; -- } -- exit (0); -- } -+ #define _HPUX_SOURCE -+ #include -+ #include -+ -+ int main () -+ { -+ #if defined(_SC_KERNEL_BITS) -+ long bits = sysconf(_SC_KERNEL_BITS); -+ #endif -+ long cpu = sysconf (_SC_CPU_VERSION); -+ -+ switch (cpu) -+ { -+ case CPU_PA_RISC1_0: puts ("hppa1.0"); break; -+ case CPU_PA_RISC1_1: puts ("hppa1.1"); break; -+ case CPU_PA_RISC2_0: -+ #if defined(_SC_KERNEL_BITS) -+ switch (bits) -+ { -+ case 64: puts ("hppa2.0w"); break; -+ case 32: puts ("hppa2.0n"); break; -+ default: puts ("hppa2.0"); break; -+ } break; -+ #else /* !defined(_SC_KERNEL_BITS) */ -+ puts ("hppa2.0"); break; -+ #endif -+ default: puts ("hppa1.0"); break; -+ } -+ exit (0); -+ } - EOF - (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` - test -z "$HP_ARCH" && HP_ARCH=hppa -@@ -730,22 +751,22 @@ - exit ;; - C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) - echo c1-convex-bsd -- exit ;; -+ exit ;; - C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) - if getsysinfo -f scalar_acc - then echo c32-convex-bsd - else echo c2-convex-bsd - fi -- exit ;; -+ exit ;; - C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) - echo c34-convex-bsd -- exit ;; -+ exit ;; - C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) - echo c38-convex-bsd -- exit ;; -+ exit ;; - C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) - echo c4-convex-bsd -- exit ;; -+ exit ;; - CRAY*Y-MP:*:*:*) - echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit ;; -@@ -769,14 +790,14 @@ - exit ;; - F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) - FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` -- FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` -- FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` -- echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" -- exit ;; -+ FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` -+ FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` -+ echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" -+ exit ;; - 5000:UNIX_System_V:4.*:*) -- FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` -- FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` -- echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" -+ FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` -+ FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` -+ echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" - exit ;; - i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) - echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} -@@ -788,30 +809,35 @@ - echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} - exit ;; - *:FreeBSD:*:*) -- case ${UNAME_MACHINE} in -- pc98) -- echo i386-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; -+ UNAME_PROCESSOR=`/usr/bin/uname -p` -+ case ${UNAME_PROCESSOR} in - amd64) - echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; - *) -- echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; -+ echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; - esac - exit ;; - i*:CYGWIN*:*) - echo ${UNAME_MACHINE}-pc-cygwin - exit ;; -+ *:MINGW64*:*) -+ echo ${UNAME_MACHINE}-pc-mingw64 -+ exit ;; - *:MINGW*:*) - echo ${UNAME_MACHINE}-pc-mingw32 - exit ;; -+ i*:MSYS*:*) -+ echo ${UNAME_MACHINE}-pc-msys -+ exit ;; - i*:windows32*:*) -- # uname -m includes "-pc" on this system. -- echo ${UNAME_MACHINE}-mingw32 -+ # uname -m includes "-pc" on this system. -+ echo ${UNAME_MACHINE}-mingw32 - exit ;; - i*:PW*:*) - echo ${UNAME_MACHINE}-pc-pw32 - exit ;; - *:Interix*:*) -- case ${UNAME_MACHINE} in -+ case ${UNAME_MACHINE} in - x86) - echo i586-pc-interix${UNAME_RELEASE} - exit ;; -@@ -848,15 +874,22 @@ - exit ;; - *:GNU:*:*) - # the GNU system -- echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` -+ echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-${LIBC}`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` - exit ;; - *:GNU/*:*:*) - # other systems with GNU libc and userland -- echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu -+ echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-${LIBC} - exit ;; - i*86:Minix:*:*) - echo ${UNAME_MACHINE}-pc-minix - exit ;; -+ aarch64:Linux:*:*) -+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC} -+ exit ;; -+ aarch64_be:Linux:*:*) -+ UNAME_MACHINE=aarch64_be -+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC} -+ exit ;; - alpha:Linux:*:*) - case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in - EV5) UNAME_MACHINE=alphaev5 ;; -@@ -866,52 +899,56 @@ - EV6) UNAME_MACHINE=alphaev6 ;; - EV67) UNAME_MACHINE=alphaev67 ;; - EV68*) UNAME_MACHINE=alphaev68 ;; -- esac -+ esac - objdump --private-headers /bin/sh | grep -q ld.so.1 -- if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi -- echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} -+ if test "$?" = 0 ; then LIBC="gnulibc1" ; fi -+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC} -+ exit ;; -+ arc:Linux:*:* | arceb:Linux:*:*) -+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC} - exit ;; - arm*:Linux:*:*) - eval $set_cc_for_build - if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ - | grep -q __ARM_EABI__ - then -- echo ${UNAME_MACHINE}-unknown-linux-gnu -+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC} - else -- echo ${UNAME_MACHINE}-unknown-linux-gnueabi -+ if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ -+ | grep -q __ARM_PCS_VFP -+ then -+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabi -+ else -+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabihf -+ fi - fi - exit ;; - avr32*:Linux:*:*) -- echo ${UNAME_MACHINE}-unknown-linux-gnu -+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC} - exit ;; - cris:Linux:*:*) -- echo cris-axis-linux-gnu -+ echo ${UNAME_MACHINE}-axis-linux-${LIBC} - exit ;; - crisv32:Linux:*:*) -- echo crisv32-axis-linux-gnu -+ echo ${UNAME_MACHINE}-axis-linux-${LIBC} - exit ;; - frv:Linux:*:*) -- echo frv-unknown-linux-gnu -+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC} -+ exit ;; -+ hexagon:Linux:*:*) -+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC} - exit ;; - i*86:Linux:*:*) -- LIBC=gnu -- eval $set_cc_for_build -- sed 's/^ //' << EOF >$dummy.c -- #ifdef __dietlibc__ -- LIBC=dietlibc -- #endif --EOF -- eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'` -- echo "${UNAME_MACHINE}-pc-linux-${LIBC}" -+ echo ${UNAME_MACHINE}-pc-linux-${LIBC} - exit ;; - ia64:Linux:*:*) -- echo ${UNAME_MACHINE}-unknown-linux-gnu -+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC} - exit ;; - m32r*:Linux:*:*) -- echo ${UNAME_MACHINE}-unknown-linux-gnu -+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC} - exit ;; - m68*:Linux:*:*) -- echo ${UNAME_MACHINE}-unknown-linux-gnu -+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC} - exit ;; - mips:Linux:*:* | mips64:Linux:*:*) - eval $set_cc_for_build -@@ -930,51 +967,57 @@ - #endif - EOF - eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'` -- test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } -+ test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; } - ;; -+ or1k:Linux:*:*) -+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC} -+ exit ;; - or32:Linux:*:*) -- echo or32-unknown-linux-gnu -+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC} - exit ;; - padre:Linux:*:*) -- echo sparc-unknown-linux-gnu -+ echo sparc-unknown-linux-${LIBC} - exit ;; - parisc64:Linux:*:* | hppa64:Linux:*:*) -- echo hppa64-unknown-linux-gnu -+ echo hppa64-unknown-linux-${LIBC} - exit ;; - parisc:Linux:*:* | hppa:Linux:*:*) - # Look for CPU level - case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in -- PA7*) echo hppa1.1-unknown-linux-gnu ;; -- PA8*) echo hppa2.0-unknown-linux-gnu ;; -- *) echo hppa-unknown-linux-gnu ;; -+ PA7*) echo hppa1.1-unknown-linux-${LIBC} ;; -+ PA8*) echo hppa2.0-unknown-linux-${LIBC} ;; -+ *) echo hppa-unknown-linux-${LIBC} ;; - esac - exit ;; - ppc64:Linux:*:*) -- echo powerpc64-unknown-linux-gnu -+ echo powerpc64-unknown-linux-${LIBC} - exit ;; - ppc:Linux:*:*) -- echo powerpc-unknown-linux-gnu -+ echo powerpc-unknown-linux-${LIBC} - exit ;; - s390:Linux:*:* | s390x:Linux:*:*) -- echo ${UNAME_MACHINE}-ibm-linux -+ echo ${UNAME_MACHINE}-ibm-linux-${LIBC} - exit ;; - sh64*:Linux:*:*) -- echo ${UNAME_MACHINE}-unknown-linux-gnu -+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC} - exit ;; - sh*:Linux:*:*) -- echo ${UNAME_MACHINE}-unknown-linux-gnu -+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC} - exit ;; - sparc:Linux:*:* | sparc64:Linux:*:*) -- echo ${UNAME_MACHINE}-unknown-linux-gnu -+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC} -+ exit ;; -+ tile*:Linux:*:*) -+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC} - exit ;; - vax:Linux:*:*) -- echo ${UNAME_MACHINE}-dec-linux-gnu -+ echo ${UNAME_MACHINE}-dec-linux-${LIBC} - exit ;; - x86_64:Linux:*:*) -- echo x86_64-unknown-linux-gnu -+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC} - exit ;; - xtensa*:Linux:*:*) -- echo ${UNAME_MACHINE}-unknown-linux-gnu -+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC} - exit ;; - i*86:DYNIX/ptx:4*:*) - # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. -@@ -983,11 +1026,11 @@ - echo i386-sequent-sysv4 - exit ;; - i*86:UNIX_SV:4.2MP:2.*) -- # Unixware is an offshoot of SVR4, but it has its own version -- # number series starting with 2... -- # I am not positive that other SVR4 systems won't match this, -+ # Unixware is an offshoot of SVR4, but it has its own version -+ # number series starting with 2... -+ # I am not positive that other SVR4 systems won't match this, - # I just have to hope. -- rms. -- # Use sysv4.2uw... so that sysv4* matches it. -+ # Use sysv4.2uw... so that sysv4* matches it. - echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} - exit ;; - i*86:OS/2:*:*) -@@ -1019,7 +1062,7 @@ - fi - exit ;; - i*86:*:5:[678]*) -- # UnixWare 7.x, OpenUNIX and OpenServer 6. -+ # UnixWare 7.x, OpenUNIX and OpenServer 6. - case `/bin/uname -X | grep "^Machine"` in - *486*) UNAME_MACHINE=i486 ;; - *Pentium) UNAME_MACHINE=i586 ;; -@@ -1047,13 +1090,13 @@ - exit ;; - pc:*:*:*) - # Left here for compatibility: -- # uname -m prints for DJGPP always 'pc', but it prints nothing about -- # the processor, so we play safe by assuming i586. -+ # uname -m prints for DJGPP always 'pc', but it prints nothing about -+ # the processor, so we play safe by assuming i586. - # Note: whatever this is, it MUST be the same as what config.sub - # prints for the "djgpp" host, or else GDB configury will decide that - # this is a cross-build. - echo i586-pc-msdosdjgpp -- exit ;; -+ exit ;; - Intel:Mach:3*:*) - echo i386-pc-mach3 - exit ;; -@@ -1088,8 +1131,8 @@ - /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ - && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; - 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) -- /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ -- && { echo i486-ncr-sysv4; exit; } ;; -+ /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ -+ && { echo i486-ncr-sysv4; exit; } ;; - NCR*:*:4.2:* | MPRAS*:*:4.2:*) - OS_REL='.3' - test -r /etc/.relid \ -@@ -1132,10 +1175,10 @@ - echo ns32k-sni-sysv - fi - exit ;; -- PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort -- # says -- echo i586-unisys-sysv4 -- exit ;; -+ PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort -+ # says -+ echo i586-unisys-sysv4 -+ exit ;; - *:UNIX_System_V:4*:FTX*) - # From Gerald Hewes . - # How about differentiating between stratus architectures? -djm -@@ -1161,11 +1204,11 @@ - exit ;; - R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) - if [ -d /usr/nec ]; then -- echo mips-nec-sysv${UNAME_RELEASE} -+ echo mips-nec-sysv${UNAME_RELEASE} - else -- echo mips-unknown-sysv${UNAME_RELEASE} -+ echo mips-unknown-sysv${UNAME_RELEASE} - fi -- exit ;; -+ exit ;; - BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. - echo powerpc-be-beos - exit ;; -@@ -1178,6 +1221,9 @@ - BePC:Haiku:*:*) # Haiku running on Intel PC compatible. - echo i586-pc-haiku - exit ;; -+ x86_64:Haiku:*:*) -+ echo x86_64-unknown-haiku -+ exit ;; - SX-4:SUPER-UX:*:*) - echo sx4-nec-superux${UNAME_RELEASE} - exit ;; -@@ -1204,19 +1250,21 @@ - exit ;; - *:Darwin:*:*) - UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown -- case $UNAME_PROCESSOR in -- i386) -- eval $set_cc_for_build -- if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then -- if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ -- (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ -- grep IS_64BIT_ARCH >/dev/null -- then -- UNAME_PROCESSOR="x86_64" -- fi -- fi ;; -- unknown) UNAME_PROCESSOR=powerpc ;; -- esac -+ eval $set_cc_for_build -+ if test "$UNAME_PROCESSOR" = unknown ; then -+ UNAME_PROCESSOR=powerpc -+ fi -+ if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then -+ if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ -+ (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ -+ grep IS_64BIT_ARCH >/dev/null -+ then -+ case $UNAME_PROCESSOR in -+ i386) UNAME_PROCESSOR=x86_64 ;; -+ powerpc) UNAME_PROCESSOR=powerpc64 ;; -+ esac -+ fi -+ fi - echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} - exit ;; - *:procnto*:*:* | *:QNX:[0123456789]*:*) -@@ -1230,7 +1278,10 @@ - *:QNX:*:4*) - echo i386-pc-qnx - exit ;; -- NSE-?:NONSTOP_KERNEL:*:*) -+ NEO-?:NONSTOP_KERNEL:*:*) -+ echo neo-tandem-nsk${UNAME_RELEASE} -+ exit ;; -+ NSE-*:NONSTOP_KERNEL:*:*) - echo nse-tandem-nsk${UNAME_RELEASE} - exit ;; - NSR-?:NONSTOP_KERNEL:*:*) -@@ -1275,13 +1326,13 @@ - echo pdp10-unknown-its - exit ;; - SEI:*:*:SEIUX) -- echo mips-sei-seiux${UNAME_RELEASE} -+ echo mips-sei-seiux${UNAME_RELEASE} - exit ;; - *:DragonFly:*:*) - echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` - exit ;; - *:*VMS:*:*) -- UNAME_MACHINE=`(uname -p) 2>/dev/null` -+ UNAME_MACHINE=`(uname -p) 2>/dev/null` - case "${UNAME_MACHINE}" in - A*) echo alpha-dec-vms ; exit ;; - I*) echo ia64-dec-vms ; exit ;; -@@ -1299,11 +1350,11 @@ - i*86:AROS:*:*) - echo ${UNAME_MACHINE}-pc-aros - exit ;; -+ x86_64:VMkernel:*:*) -+ echo ${UNAME_MACHINE}-unknown-esx -+ exit ;; - esac - --#echo '(No uname command or uname output not recognized.)' 1>&2 --#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 -- - eval $set_cc_for_build - cat >$dummy.c < - printf ("m68k-sony-newsos%s\n", - #ifdef NEWSOS4 -- "4" -+ "4" - #else -- "" -+ "" - #endif -- ); exit (0); -+ ); exit (0); - #endif - #endif - -Index: b/config.sub -=================================================================== ---- a/config.sub -+++ b/config.sub -@@ -1,38 +1,31 @@ - #! /bin/sh - # Configuration validation subroutine script. --# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, --# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 --# Free Software Foundation, Inc. -- --timestamp='2009-11-20' -- --# This file is (in principle) common to ALL GNU software. --# The presence of a machine in this file suggests that SOME GNU software --# can handle that machine. It does not imply ALL GNU software can. --# --# This file 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 -+# Copyright 1992-2013 Free Software Foundation, Inc. -+ -+timestamp='2013-04-24' -+ -+# This file 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 3 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. -+# 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., 51 Franklin Street - Fifth Floor, Boston, MA --# 02110-1301, USA. -+# along with this program; if not, see . - # - # As a special exception to the GNU General Public License, if you - # distribute this file as part of a program that contains a - # configuration script generated by Autoconf, you may include it under --# the same distribution terms that you use for the rest of that program. -+# the same distribution terms that you use for the rest of that -+# program. This Exception is an additional permission under section 7 -+# of the GNU General Public License, version 3 ("GPLv3"). - - --# Please send patches to . Submit a context --# diff and a properly formatted GNU ChangeLog entry. -+# Please send patches with a ChangeLog entry to config-patches@gnu.org. - # - # Configuration subroutine to validate and canonicalize a configuration type. - # Supply the specified configuration type as an argument. -@@ -75,8 +68,7 @@ - version="\ - GNU config.sub ($timestamp) - --Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, --2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. -+Copyright 1992-2013 Free Software Foundation, Inc. - - This is free software; see the source for copying conditions. There is NO - warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." -@@ -123,13 +115,18 @@ - # Here we must recognize all the valid KERNEL-OS combinations. - maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` - case $maybe_os in -- nto-qnx* | linux-gnu* | linux-dietlibc | linux-newlib* | linux-uclibc* | \ -- uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | \ -+ nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \ -+ linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \ -+ knetbsd*-gnu* | netbsd*-gnu* | \ - kopensolaris*-gnu* | \ - storm-chaos* | os2-emx* | rtmk-nova*) - os=-$maybe_os - basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` - ;; -+ android-linux) -+ os=-linux-android -+ basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown -+ ;; - *) - basic_machine=`echo $1 | sed 's/-[^-]*$//'` - if [ $basic_machine != $1 ] -@@ -152,12 +149,12 @@ - -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ - -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ - -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ -- -apple | -axis | -knuth | -cray | -microblaze) -+ -apple | -axis | -knuth | -cray | -microblaze*) - os= - basic_machine=$1 - ;; -- -bluegene*) -- os=-cnk -+ -bluegene*) -+ os=-cnk - ;; - -sim | -cisco | -oki | -wec | -winbond) - os= -@@ -173,10 +170,10 @@ - os=-chorusos - basic_machine=$1 - ;; -- -chorusrdb) -- os=-chorusrdb -+ -chorusrdb) -+ os=-chorusrdb - basic_machine=$1 -- ;; -+ ;; - -hiux*) - os=-hiuxwe2 - ;; -@@ -221,6 +218,12 @@ - -isc*) - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; -+ -lynx*178) -+ os=-lynxos178 -+ ;; -+ -lynx*5) -+ os=-lynxos5 -+ ;; - -lynx*) - os=-lynxos - ;; -@@ -245,20 +248,27 @@ - # Some are omitted here because they have special meanings below. - 1750a | 580 \ - | a29k \ -+ | aarch64 | aarch64_be \ - | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ - | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ - | am33_2.0 \ -- | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \ -+ | arc | arceb \ -+ | arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \ -+ | avr | avr32 \ -+ | be32 | be64 \ - | bfin \ - | c4x | clipper \ - | d10v | d30v | dlx | dsp16xx \ -+ | epiphany \ - | fido | fr30 | frv \ - | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ -+ | hexagon \ - | i370 | i860 | i960 | ia64 \ - | ip2k | iq2000 \ -+ | le32 | le64 \ - | lm32 \ - | m32c | m32r | m32rle | m68000 | m68k | m88k \ -- | maxq | mb | microblaze | mcore | mep | metag \ -+ | maxq | mb | microblaze | microblazeel | mcore | mep | metag \ - | mips | mipsbe | mipseb | mipsel | mipsle \ - | mips16 \ - | mips64 | mips64el \ -@@ -276,34 +286,45 @@ - | mipsisa64r2 | mipsisa64r2el \ - | mipsisa64sb1 | mipsisa64sb1el \ - | mipsisa64sr71k | mipsisa64sr71kel \ -+ | mipsr5900 | mipsr5900el \ - | mipstx39 | mipstx39el \ - | mn10200 | mn10300 \ - | moxie \ - | mt \ - | msp430 \ -- | nios | nios2 \ -+ | nds32 | nds32le | nds32be \ -+ | nios | nios2 | nios2eb | nios2el \ - | ns16k | ns32k \ -- | or32 \ -+ | open8 \ -+ | or1k | or32 \ - | pdp10 | pdp11 | pj | pjl \ -- | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \ -+ | powerpc | powerpc64 | powerpc64le | powerpcle \ - | pyramid \ -- | rx \ -+ | rl78 | rx \ - | score \ - | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ - | sh64 | sh64le \ - | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ - | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ -- | spu | strongarm \ -- | tahoe | thumb | tic4x | tic80 | tron \ -+ | spu \ -+ | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \ - | ubicom32 \ -- | v850 | v850e \ -+ | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \ - | we32k \ -- | x86 | xc16x | xscale | xscalee[bl] | xstormy16 | xtensa \ -+ | x86 | xc16x | xstormy16 | xtensa \ - | z8k | z80) - basic_machine=$basic_machine-unknown - ;; -- m6811 | m68hc11 | m6812 | m68hc12 | picochip) -- # Motorola 68HC11/12. -+ c54x) -+ basic_machine=tic54x-unknown -+ ;; -+ c55x) -+ basic_machine=tic55x-unknown -+ ;; -+ c6x) -+ basic_machine=tic6x-unknown -+ ;; -+ m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | picochip) - basic_machine=$basic_machine-unknown - os=-none - ;; -@@ -313,6 +334,21 @@ - basic_machine=mt-unknown - ;; - -+ strongarm | thumb | xscale) -+ basic_machine=arm-unknown -+ ;; -+ xgate) -+ basic_machine=$basic_machine-unknown -+ os=-none -+ ;; -+ xscaleeb) -+ basic_machine=armeb-unknown -+ ;; -+ -+ xscaleel) -+ basic_machine=armel-unknown -+ ;; -+ - # We use `pc' rather than `unknown' - # because (1) that's what they normally are, and - # (2) the word "unknown" tends to confuse beginning users. -@@ -327,25 +363,30 @@ - # Recognize the basic CPU types with company name. - 580-* \ - | a29k-* \ -+ | aarch64-* | aarch64_be-* \ - | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ - | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ -- | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ -+ | alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \ - | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ - | avr-* | avr32-* \ -+ | be32-* | be64-* \ - | bfin-* | bs2000-* \ -- | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \ -+ | c[123]* | c30-* | [cjt]90-* | c4x-* \ - | clipper-* | craynv-* | cydra-* \ - | d10v-* | d30v-* | dlx-* \ - | elxsi-* \ - | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ - | h8300-* | h8500-* \ - | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ -+ | hexagon-* \ - | i*86-* | i860-* | i960-* | ia64-* \ - | ip2k-* | iq2000-* \ -+ | le32-* | le64-* \ - | lm32-* \ - | m32c-* | m32r-* | m32rle-* \ - | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ -- | m88110-* | m88k-* | maxq-* | mcore-* | metag-* | microblaze-* \ -+ | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \ -+ | microblaze-* | microblazeel-* \ - | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ - | mips16-* \ - | mips64-* | mips64el-* \ -@@ -363,29 +404,34 @@ - | mipsisa64r2-* | mipsisa64r2el-* \ - | mipsisa64sb1-* | mipsisa64sb1el-* \ - | mipsisa64sr71k-* | mipsisa64sr71kel-* \ -+ | mipsr5900-* | mipsr5900el-* \ - | mipstx39-* | mipstx39el-* \ - | mmix-* \ - | mt-* \ - | msp430-* \ -- | nios-* | nios2-* \ -+ | nds32-* | nds32le-* | nds32be-* \ -+ | nios-* | nios2-* | nios2eb-* | nios2el-* \ - | none-* | np1-* | ns16k-* | ns32k-* \ -+ | open8-* \ - | orion-* \ - | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ -- | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \ -+ | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \ - | pyramid-* \ -- | romp-* | rs6000-* | rx-* \ -+ | rl78-* | romp-* | rs6000-* | rx-* \ - | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ - | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ - | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ - | sparclite-* \ -- | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | strongarm-* | sv1-* | sx?-* \ -- | tahoe-* | thumb-* \ -- | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* | tile-* \ -+ | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \ -+ | tahoe-* \ -+ | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ -+ | tile*-* \ - | tron-* \ - | ubicom32-* \ -- | v850-* | v850e-* | vax-* \ -+ | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \ -+ | vax-* \ - | we32k-* \ -- | x86-* | x86_64-* | xc16x-* | xps100-* | xscale-* | xscalee[bl]-* \ -+ | x86-* | x86_64-* | xc16x-* | xps100-* \ - | xstormy16-* | xtensa*-* \ - | ymp-* \ - | z8k-* | z80-*) -@@ -410,7 +456,7 @@ - basic_machine=a29k-amd - os=-udi - ;; -- abacus) -+ abacus) - basic_machine=abacus-unknown - ;; - adobe68k) -@@ -480,11 +526,20 @@ - basic_machine=powerpc-ibm - os=-cnk - ;; -+ c54x-*) -+ basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'` -+ ;; -+ c55x-*) -+ basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'` -+ ;; -+ c6x-*) -+ basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'` -+ ;; - c90) - basic_machine=c90-cray - os=-unicos - ;; -- cegcc) -+ cegcc) - basic_machine=arm-unknown - os=-cegcc - ;; -@@ -516,7 +571,7 @@ - basic_machine=craynv-cray - os=-unicosmp - ;; -- cr16) -+ cr16 | cr16-*) - basic_machine=cr16-unknown - os=-elf - ;; -@@ -674,7 +729,6 @@ - i370-ibm* | ibm*) - basic_machine=i370-ibm - ;; --# I'm not sure what "Sysv32" means. Should this be sysv3.2? - i*86v32) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` - os=-sysv32 -@@ -732,9 +786,13 @@ - basic_machine=ns32k-utek - os=-sysv - ;; -- microblaze) -+ microblaze*) - basic_machine=microblaze-xilinx - ;; -+ mingw64) -+ basic_machine=x86_64-pc -+ os=-mingw64 -+ ;; - mingw32) - basic_machine=i386-pc - os=-mingw32 -@@ -771,10 +829,18 @@ - ms1-*) - basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` - ;; -+ msys) -+ basic_machine=i386-pc -+ os=-msys -+ ;; - mvs) - basic_machine=i370-ibm - os=-mvs - ;; -+ nacl) -+ basic_machine=le32-unknown -+ os=-nacl -+ ;; - ncr3000) - basic_machine=i486-ncr - os=-sysv4 -@@ -839,6 +905,12 @@ - np1) - basic_machine=np1-gould - ;; -+ neo-tandem) -+ basic_machine=neo-tandem -+ ;; -+ nse-tandem) -+ basic_machine=nse-tandem -+ ;; - nsr-tandem) - basic_machine=nsr-tandem - ;; -@@ -921,9 +993,10 @@ - ;; - power) basic_machine=power-ibm - ;; -- ppc) basic_machine=powerpc-unknown -+ ppc | ppcbe) basic_machine=powerpc-unknown - ;; -- ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` -+ ppc-* | ppcbe-*) -+ basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - ppcle | powerpclittle | ppc-le | powerpc-little) - basic_machine=powerpcle-unknown -@@ -948,7 +1021,11 @@ - basic_machine=i586-unknown - os=-pw32 - ;; -- rdos) -+ rdos | rdos64) -+ basic_machine=x86_64-pc -+ os=-rdos -+ ;; -+ rdos32) - basic_machine=i386-pc - os=-rdos - ;; -@@ -1017,6 +1094,9 @@ - basic_machine=i860-stratus - os=-sysv4 - ;; -+ strongarm-* | thumb-*) -+ basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'` -+ ;; - sun2) - basic_machine=m68000-sun - ;; -@@ -1073,20 +1153,8 @@ - basic_machine=t90-cray - os=-unicos - ;; -- tic54x | c54x*) -- basic_machine=tic54x-unknown -- os=-coff -- ;; -- tic55x | c55x*) -- basic_machine=tic55x-unknown -- os=-coff -- ;; -- tic6x | c6x*) -- basic_machine=tic6x-unknown -- os=-coff -- ;; - tile*) -- basic_machine=tile-unknown -+ basic_machine=$basic_machine-unknown - os=-linux-gnu - ;; - tx39) -@@ -1156,6 +1224,9 @@ - xps | xps100) - basic_machine=xps100-honeywell - ;; -+ xscale-* | xscalee[bl]-*) -+ basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'` -+ ;; - ymp) - basic_machine=ymp-cray - os=-unicos -@@ -1253,11 +1324,11 @@ - if [ x"$os" != x"" ] - then - case $os in -- # First match some system type aliases -- # that might get confused with valid system types. -+ # First match some system type aliases -+ # that might get confused with valid system types. - # -solaris* is a basic system type, with this one exception. -- -auroraux) -- os=-auroraux -+ -auroraux) -+ os=-auroraux - ;; - -solaris1 | -solaris1.*) - os=`echo $os | sed -e 's|solaris1|sunos4|'` -@@ -1281,20 +1352,21 @@ - -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ - | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\ - | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \ -- | -sym* | -kopensolaris* \ -+ | -sym* | -kopensolaris* | -plan9* \ - | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ - | -aos* | -aros* \ - | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ - | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ - | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ -- | -openbsd* | -solidbsd* \ -+ | -bitrig* | -openbsd* | -solidbsd* \ - | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ - | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ - | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ - | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ - | -chorusos* | -chorusrdb* | -cegcc* \ -- | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ -- | -mingw32* | -linux-gnu* | -linux-newlib* | -linux-uclibc* \ -+ | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ -+ | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \ -+ | -linux-newlib* | -linux-musl* | -linux-uclibc* \ - | -uxpv* | -beos* | -mpeix* | -udk* \ - | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ - | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ -@@ -1341,7 +1413,7 @@ - -opened*) - os=-openedition - ;; -- -os400*) -+ -os400*) - os=-os400 - ;; - -wince*) -@@ -1390,7 +1462,7 @@ - -sinix*) - os=-sysv4 - ;; -- -tpf*) -+ -tpf*) - os=-tpf - ;; - -triton*) -@@ -1426,15 +1498,14 @@ - -aros*) - os=-aros - ;; -- -kaos*) -- os=-kaos -- ;; - -zvmoe) - os=-zvmoe - ;; - -dicos*) - os=-dicos - ;; -+ -nacl*) -+ ;; - -none) - ;; - *) -@@ -1457,10 +1528,10 @@ - # system, and we'll never get to this point. - - case $basic_machine in -- score-*) -+ score-*) - os=-elf - ;; -- spu-*) -+ spu-*) - os=-elf - ;; - *-acorn) -@@ -1472,8 +1543,20 @@ - arm*-semi) - os=-aout - ;; -- c4x-* | tic4x-*) -- os=-coff -+ c4x-* | tic4x-*) -+ os=-coff -+ ;; -+ hexagon-*) -+ os=-elf -+ ;; -+ tic54x-*) -+ os=-coff -+ ;; -+ tic55x-*) -+ os=-coff -+ ;; -+ tic6x-*) -+ os=-coff - ;; - # This must come before the *-dec entry. - pdp10-*) -@@ -1493,14 +1576,11 @@ - ;; - m68000-sun) - os=-sunos3 -- # This also exists in the configure program, but was not the -- # default. -- # os=-sunos4 - ;; - m68*-cisco) - os=-aout - ;; -- mep-*) -+ mep-*) - os=-elf - ;; - mips*-cisco) -@@ -1509,6 +1589,9 @@ - mips*-*) - os=-elf - ;; -+ or1k-*) -+ os=-elf -+ ;; - or32-*) - os=-coff - ;; -@@ -1527,7 +1610,7 @@ - *-ibm) - os=-aix - ;; -- *-knuth) -+ *-knuth) - os=-mmixware - ;; - *-wec) diff -Nru lcms2-2.5/debian/patches/endianness-verification-fix-powerpc.patch lcms2-2.6/debian/patches/endianness-verification-fix-powerpc.patch --- lcms2-2.5/debian/patches/endianness-verification-fix-powerpc.patch 1970-01-01 00:00:00.000000000 +0000 +++ lcms2-2.6/debian/patches/endianness-verification-fix-powerpc.patch 2014-06-16 15:15:31.000000000 +0000 @@ -0,0 +1,22 @@ +Description: Fix endianness verification for powerpc +Author: "Fernando Seiti Furusato" +Origin: other, https://bugs.debian.org/750686 +Bug-Debian: https://bugs.debian.org/750686 +Last-Update: 2014-06-08 +--- +This patch header follows DEP-3: http://dep.debian.net/deps/dep3/ +--- a/include/lcms2.h ++++ b/include/lcms2.h +@@ -192,11 +192,9 @@ + + #if defined(__powerpc__) || defined(__ppc__) || defined(TARGET_CPU_PPC) + # define CMS_USE_BIG_ENDIAN 1 +-# if defined (__GNUC__) && defined(__BYTE_ORDER) && defined(__LITTLE_ENDIAN) +-# if __BYTE_ORDER == __LITTLE_ENDIAN ++# if defined (__GNUC__) && defined(__LITTLE_ENDIAN__) + // // Don't use big endian for PowerPC little endian mode + # undef CMS_USE_BIG_ENDIAN +-# endif + # endif + #endif + diff -Nru lcms2-2.5/debian/patches/fix-cmsnamed-alignment-issue.patch lcms2-2.6/debian/patches/fix-cmsnamed-alignment-issue.patch --- lcms2-2.5/debian/patches/fix-cmsnamed-alignment-issue.patch 1970-01-01 00:00:00.000000000 +0000 +++ lcms2-2.6/debian/patches/fix-cmsnamed-alignment-issue.patch 2014-06-19 12:01:14.000000000 +0000 @@ -0,0 +1,122 @@ +Author: Michael Cree +Description: fix alignment issues when casting chars to shorts + On alpha, we want our unsigned shorts to be 16-bit aligned; when casting + from a char * to an unsigned short *, this is not guaranteed, as the char * + may be only 8-bit aligned. So make the appropriate alignment fix-ups in + the relevant functions, fixing a FTBFS on alpha. +Bug-Debian: http://bugs.debian.org/644473 + +--- a/src/cmsnamed.c ++++ b/src/cmsnamed.c +@@ -185,8 +185,19 @@ + cmsUInt32Number i, len = (cmsUInt32Number) strlen(ASCIIString)+1; + wchar_t* WStr; + cmsBool rc; +- cmsUInt16Number Lang = _cmsAdjustEndianess16(*(cmsUInt16Number*) LanguageCode); +- cmsUInt16Number Cntry = _cmsAdjustEndianess16(*(cmsUInt16Number*) CountryCode); ++ union { ++ cmsUInt16Number uint16; ++ char str[2]; ++ } code_convert; ++ cmsUInt16Number Lang; ++ cmsUInt16Number Cntry; ++ ++ code_convert.str[0] = LanguageCode[0]; ++ code_convert.str[1] = LanguageCode[1]; ++ Lang = _cmsAdjustEndianess16(code_convert.uint16); ++ code_convert.str[0] = CountryCode[0]; ++ code_convert.str[1] = CountryCode[1]; ++ Cntry = _cmsAdjustEndianess16(code_convert.uint16); + + if (mlu == NULL) return FALSE; + +@@ -220,9 +231,20 @@ + // Add a wide entry + cmsBool CMSEXPORT cmsMLUsetWide(cmsMLU* mlu, const char Language[3], const char Country[3], const wchar_t* WideString) + { +- cmsUInt16Number Lang = _cmsAdjustEndianess16(*(cmsUInt16Number*) Language); +- cmsUInt16Number Cntry = _cmsAdjustEndianess16(*(cmsUInt16Number*) Country); + cmsUInt32Number len; ++ union { ++ cmsUInt16Number uint16; ++ char str[2]; ++ } code_convert; ++ cmsUInt16Number Lang; ++ cmsUInt16Number Cntry; ++ ++ code_convert.str[0] = Language[0]; ++ code_convert.str[1] = Language[1]; ++ Lang = _cmsAdjustEndianess16(code_convert.uint16); ++ code_convert.str[0] = Country[0]; ++ code_convert.str[1] = Country[1]; ++ Cntry = _cmsAdjustEndianess16(code_convert.uint16); + + if (mlu == NULL) return FALSE; + if (WideString == NULL) return FALSE; +@@ -350,8 +372,19 @@ + cmsUInt32Number StrLen = 0; + cmsUInt32Number ASCIIlen, i; + +- cmsUInt16Number Lang = _cmsAdjustEndianess16(*(cmsUInt16Number*) LanguageCode); +- cmsUInt16Number Cntry = _cmsAdjustEndianess16(*(cmsUInt16Number*) CountryCode); ++ union { ++ cmsUInt16Number uint16; ++ char str[2]; ++ } code_convert; ++ cmsUInt16Number Lang; ++ cmsUInt16Number Cntry; ++ ++ code_convert.str[0] = LanguageCode[0]; ++ code_convert.str[1] = LanguageCode[1]; ++ Lang = _cmsAdjustEndianess16(code_convert.uint16); ++ code_convert.str[0] = CountryCode[0]; ++ code_convert.str[1] = CountryCode[1]; ++ Cntry = _cmsAdjustEndianess16(code_convert.uint16); + + // Sanitize + if (mlu == NULL) return 0; +@@ -394,8 +427,19 @@ + const wchar_t *Wide; + cmsUInt32Number StrLen = 0; + +- cmsUInt16Number Lang = _cmsAdjustEndianess16(*(cmsUInt16Number*) LanguageCode); +- cmsUInt16Number Cntry = _cmsAdjustEndianess16(*(cmsUInt16Number*) CountryCode); ++ union { ++ cmsUInt16Number uint16; ++ char str[2]; ++ } code_convert; ++ cmsUInt16Number Lang; ++ cmsUInt16Number Cntry; ++ ++ code_convert.str[0] = LanguageCode[0]; ++ code_convert.str[1] = LanguageCode[1]; ++ Lang = _cmsAdjustEndianess16(code_convert.uint16); ++ code_convert.str[0] = CountryCode[0]; ++ code_convert.str[1] = CountryCode[1]; ++ Cntry = _cmsAdjustEndianess16(code_convert.uint16); + + // Sanitize + if (mlu == NULL) return 0; +@@ -426,10 +470,19 @@ + char ObtainedLanguage[3], char ObtainedCountry[3]) + { + const wchar_t *Wide; ++ cmsUInt16Number ObtLang, ObtCode; + +- cmsUInt16Number Lang = _cmsAdjustEndianess16(*(cmsUInt16Number*) LanguageCode); +- cmsUInt16Number Cntry = _cmsAdjustEndianess16(*(cmsUInt16Number*) CountryCode); +- cmsUInt16Number ObtLang, ObtCode; ++ union { ++ cmsUInt16Number uint16; ++ char str[3]; ++ } code_convert; ++ cmsUInt16Number Lang; ++ cmsUInt16Number Cntry; ++ ++ strcpy(code_convert.str, LanguageCode); ++ Lang = _cmsAdjustEndianess16(code_convert.uint16); ++ strcpy(code_convert.str, CountryCode); ++ Cntry = _cmsAdjustEndianess16(code_convert.uint16); + + // Sanitize + if (mlu == NULL) return FALSE; diff -Nru lcms2-2.5/debian/patches/fix-floating-point-rounding-in-version-numbers.diff lcms2-2.6/debian/patches/fix-floating-point-rounding-in-version-numbers.diff --- lcms2-2.5/debian/patches/fix-floating-point-rounding-in-version-numbers.diff 2014-01-16 06:41:58.000000000 +0000 +++ lcms2-2.6/debian/patches/fix-floating-point-rounding-in-version-numbers.diff 1970-01-01 00:00:00.000000000 +0000 @@ -1,68 +0,0 @@ -Description: Fix writing of version header to ICC files -Author: Christopher Halse Rogers -Forwarded: https://github.com/mm2/Little-CMS/pull/27 - ---- a/testbed/testcms2.c -+++ b/testbed/testcms2.c -@@ -5083,6 +5083,41 @@ - } - - -+static -+cmsInt32Number CheckVersionHeaderWriting(void) -+{ -+ cmsHPROFILE h; -+ int index; -+ float test_versions[] = { -+ 2.3, -+ 4.08, -+ 4.09, -+ 4.3 -+ }; -+ -+ for (index = 0; index < sizeof(test_versions)/sizeof(test_versions[0]); index++) { -+ h = cmsCreateProfilePlaceholder(DbgThread()); -+ if (h == NULL) return 0; -+ -+ cmsSetProfileVersion(h, test_versions[index]); -+ -+ cmsSaveProfileToFile(h, "alltags.icc"); -+ cmsCloseProfile(h); -+ -+ h = cmsOpenProfileFromFileTHR(DbgThread(), "alltags.icc", "r"); -+ -+ // Only the first 3 digits are significant -+ if (fabs(cmsGetProfileVersion(h) - test_versions[index]) > 0.005) { -+ Fail("Version failed to round-trip: wrote %.2f, read %.2f", -+ test_versions[index], cmsGetProfileVersion(h)); -+ return 0; -+ } -+ cmsCloseProfile(h); -+ remove("alltags.icc"); -+ } -+ return 1; -+} -+ - // This is a very big test that checks every single tag - static - cmsInt32Number CheckProfileCreation(void) -@@ -8303,7 +8338,7 @@ - - // Profile I/O (this one is huge!) - Check("Profile creation", CheckProfileCreation); -- -+ Check("Header version", CheckVersionHeaderWriting); - - // Error reporting - Check("Error reporting on bad profiles", CheckErrReportingOnBadProfiles); ---- a/src/cmsio0.c -+++ b/src/cmsio0.c -@@ -925,7 +925,7 @@ - - // 4.2 -> 0x4200000 - -- Icc -> Version = BaseToBase((cmsUInt32Number) floor(Version * 100.0), 10, 16) << 16; -+ Icc -> Version = BaseToBase((cmsUInt32Number) round(Version * 100.0), 10, 16) << 16; - } - - cmsFloat64Number CMSEXPORT cmsGetProfileVersion(cmsHPROFILE hProfile) diff -Nru lcms2-2.5/debian/patches/fix-unaligned-access.patch lcms2-2.6/debian/patches/fix-unaligned-access.patch --- lcms2-2.5/debian/patches/fix-unaligned-access.patch 1970-01-01 00:00:00.000000000 +0000 +++ lcms2-2.6/debian/patches/fix-unaligned-access.patch 2014-06-16 15:15:31.000000000 +0000 @@ -0,0 +1,25 @@ +Description: Align access for double value on mips/mipsel + This is the patch #2 of the proposed solutions in the Debian bug report. +Author: Aurelien Jarno +Origin: Debian, https://bugs.debian.org/749975 +Bug: https://github.com/mm2/Little-CMS/issues/32 +Last-Update: 2014-06-05 +--- +This patch header follows DEP-3: http://dep.debian.net/deps/dep3/ +--- a/src/lcms2_internal.h ++++ b/src/lcms2_internal.h +@@ -479,11 +479,13 @@ + const struct _cmsContext_struct* src); + + // Container for adaptation state -- not a plug-in ++// The chunks are only guaranteed to be aligned to void *, tell that to the ++// compiler so that it can generate unaligned access instructions if needed. + typedef struct { + + cmsFloat64Number AdaptationState; + +-} _cmsAdaptationStateChunkType; ++} _cmsAdaptationStateChunkType __attribute__ ((__aligned__(__alignof__(void *)))); + + // The global Context0 storage for adaptation state + extern _cmsAdaptationStateChunkType _cmsAdaptationStateChunk; diff -Nru lcms2-2.5/debian/patches/jpgicc.1 lcms2-2.6/debian/patches/jpgicc.1 --- lcms2-2.5/debian/patches/jpgicc.1 2012-11-29 21:24:05.000000000 +0000 +++ lcms2-2.6/debian/patches/jpgicc.1 1970-01-01 00:00:00.000000000 +0000 @@ -1,11 +0,0 @@ ---- lcms2-2.1.orig/utils/jpgicc/jpgicc.1 -+++ lcms2-2.1/utils/jpgicc/jpgicc.1 -@@ -37,7 +37,7 @@ - Soft proof profile - .TP - .BI \-o\ profile --.p -+.TP - Output profile (defaults to sRGB). - .TP - .B \-q <0..100> diff -Nru lcms2-2.5/debian/patches/powerpc64le.patch lcms2-2.6/debian/patches/powerpc64le.patch --- lcms2-2.5/debian/patches/powerpc64le.patch 2013-12-11 10:37:15.000000000 +0000 +++ lcms2-2.6/debian/patches/powerpc64le.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,55 +0,0 @@ -Description: patch aclocal.m4 for ppc64el and regen configure. -Author: Adam Conrad - ---- lcms2-2.5.orig/aclocal.m4 -+++ lcms2-2.5/aclocal.m4 -@@ -1298,7 +1298,10 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux* - x86_64-*linux*) - LD="${LD-ld} -m elf_i386" - ;; -- ppc64-*linux*|powerpc64-*linux*) -+ powerpc64le-*) -+ LD="${LD-ld} -m elf32lppclinux" -+ ;; -+ powerpc64-*) - LD="${LD-ld} -m elf32ppclinux" - ;; - s390x-*linux*) -@@ -1317,7 +1320,10 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux* - x86_64-*linux*) - LD="${LD-ld} -m elf_x86_64" - ;; -- ppc*-*linux*|powerpc*-*linux*) -+ powerpcle-*) -+ LD="${LD-ld} -m elf64lppc" -+ ;; -+ powerpc-*) - LD="${LD-ld} -m elf64ppc" - ;; - s390*-*linux*|s390*-*tpf*) ---- lcms2-2.5.orig/configure -+++ lcms2-2.5/configure -@@ -7500,7 +7500,10 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux* - x86_64-*linux*) - LD="${LD-ld} -m elf_i386" - ;; -- ppc64-*linux*|powerpc64-*linux*) -+ powerpc64le-*) -+ LD="${LD-ld} -m elf32lppclinux" -+ ;; -+ powerpc64-*) - LD="${LD-ld} -m elf32ppclinux" - ;; - s390x-*linux*) -@@ -7519,7 +7522,10 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux* - x86_64-*linux*) - LD="${LD-ld} -m elf_x86_64" - ;; -- ppc*-*linux*|powerpc*-*linux*) -+ powerpcle-*) -+ LD="${LD-ld} -m elf64lppc" -+ ;; -+ powerpc-*) - LD="${LD-ld} -m elf64ppc" - ;; - s390*-*linux*|s390*-*tpf*) diff -Nru lcms2-2.5/debian/patches/prepare-for-libtoolizing.patch lcms2-2.6/debian/patches/prepare-for-libtoolizing.patch --- lcms2-2.5/debian/patches/prepare-for-libtoolizing.patch 1970-01-01 00:00:00.000000000 +0000 +++ lcms2-2.6/debian/patches/prepare-for-libtoolizing.patch 2014-06-19 12:01:14.000000000 +0000 @@ -0,0 +1,51 @@ +Description: Link transicc and testbed binaries against libmath + The bug fix for Debian bug #745748 (introduction of ppc64el) requires running + libtool at build time. This results in some unresolved sybmols due to a missing + linkage to libmath. +Author: Thomas Weber +Bug: +Bug-Debian: https://bugs.debian.org/745748 +Forwarded: +Applied-Upstream: +--- +This patch header follows DEP-3: http://dep.debian.net/deps/dep3/ +--- a/configure.ac ++++ b/configure.ac +@@ -355,6 +355,15 @@ + TIFFICC_DEPLIBS=`echo $TIFFICC_DEPLIBS | sed -e 's/ */ /g'` + AC_SUBST(TIFFICC_DEPLIBS) + ++# Libraries that the transicc program depends on ++TRANSICC_DEPLIBS="$LIB_MATH" ++TRANSICC_DEPLIBS=`echo $TRANSICC_DEPLIBS | sed -e 's/ */ /g'` ++AC_SUBST(TRANSICC_DEPLIBS) ++ ++# Libraries that the testbed programs depends on ++TESTBED_DEPLIBS="$LIB_MATH" ++TESTBED_DEPLIBS=`echo $TESTBED_DEPLIBS | sed -e 's/ */ /g'` ++AC_SUBST(TESTBED_DEPLIBS) + LIBS='' + + # +--- a/testbed/Makefile.am ++++ b/testbed/Makefile.am +@@ -11,7 +11,7 @@ + + # CFLAGS = --pedantic -Wall -std=c99 -O2 + +-testcms_LDADD = $(top_builddir)/src/liblcms2.la ++testcms_LDADD = $(top_builddir)/src/liblcms2.la @TESTBED_DEPLIBS@ + testcms_LDFLAGS = @LDFLAGS@ + testcms_SOURCES = testcms2.c testplugin.c zoo_icc.c testcms2.h + +--- a/utils/transicc/Makefile.am ++++ b/utils/transicc/Makefile.am +@@ -11,7 +11,7 @@ + + bin_PROGRAMS = transicc + +-transicc_LDADD = $(top_builddir)/src/liblcms2.la ++transicc_LDADD = $(top_builddir)/src/liblcms2.la @TRANSICC_DEPLIBS@ + transicc_LDFLAGS = @LDFLAGS@ + transicc_SOURCES = transicc.c ../common/xgetopt.c ../common/vprf.c ../common/utils.h + transicc_MANS = transicc.1 diff -Nru lcms2-2.5/debian/patches/sanity-check-profiles-CVE-2014-0459.patch lcms2-2.6/debian/patches/sanity-check-profiles-CVE-2014-0459.patch --- lcms2-2.5/debian/patches/sanity-check-profiles-CVE-2014-0459.patch 1970-01-01 00:00:00.000000000 +0000 +++ lcms2-2.6/debian/patches/sanity-check-profiles-CVE-2014-0459.patch 2014-06-19 12:01:14.000000000 +0000 @@ -0,0 +1,121 @@ +Description: Sanity check the profile version, fix for CVE-2014-0459 + The patch was changed to still call cmsWhitePointFromTemp(), + see https://github.com/mm2/Little-CMS/issues/30 +Origin: upstream, https://github.com/mm2/Little-CMS/commit/74ba391 +Bug: https://github.com/mm2/Little-CMS/issues/29 +Bug-Debian: https://bugs.debian.org/745471 +Forwarded: not-needed +Applied-Upstream: https://github.com/mm2/Little-CMS/commit/74ba391 +Last-Update: 2014-04-25 +--- +This patch header follows DEP-3: http://dep.debian.net/deps/dep3/ +--- a/src/cmscnvrt.c ++++ b/src/cmscnvrt.c +@@ -1045,7 +1045,7 @@ + if (TheIntents[i] == INTENT_PERCEPTUAL || TheIntents[i] == INTENT_SATURATION) { + + // Force BPC for V4 profiles in perceptual and saturation +- if (cmsGetProfileVersion(hProfiles[i]) >= 4.0) ++ if (cmsGetEncodedICCversion(hProfiles[i]) >= 0x4000000) + BPC[i] = TRUE; + } + } +--- a/src/cmsintrp.c ++++ b/src/cmsintrp.c +@@ -929,7 +929,7 @@ + + Rest = c1 * rx + c2 * ry + c3 * rz; + +- Tmp1[OutChan] = (cmsUInt16Number) c0 + ROUND_FIXED_TO_INT(_cmsToFixedDomain(Rest)); ++ Tmp1[OutChan] = (cmsUInt16Number) ( c0 + ROUND_FIXED_TO_INT(_cmsToFixedDomain(Rest))); + } + + +@@ -993,7 +993,7 @@ + + Rest = c1 * rx + c2 * ry + c3 * rz; + +- Tmp2[OutChan] = (cmsUInt16Number) c0 + ROUND_FIXED_TO_INT(_cmsToFixedDomain(Rest)); ++ Tmp2[OutChan] = (cmsUInt16Number) (c0 + ROUND_FIXED_TO_INT(_cmsToFixedDomain(Rest))); + } + + +--- a/src/cmsio0.c ++++ b/src/cmsio0.c +@@ -623,6 +623,32 @@ + } + + ++ ++// Enforces that the profile version is per. spec. ++// Operates on the big endian bytes from the profile. ++// Called before converting to platform endianness. ++// Byte 0 is BCD major version, so max 9. ++// Byte 1 is 2 BCD digits, one per nibble. ++// Reserved bytes 2 & 3 must be 0. ++static ++cmsUInt32Number _validatedVersion(cmsUInt32Number DWord) ++{ ++ cmsUInt8Number* pByte = (cmsUInt8Number*) &DWord; ++ cmsUInt8Number temp1; ++ cmsUInt8Number temp2; ++ ++ if (*pByte > 0x09) *pByte = (cmsUInt8Number) 0x09; ++ temp1 = *(pByte+1) & 0xf0; ++ temp2 = *(pByte+1) & 0x0f; ++ if (temp1 > 0x90) temp1 = 0x90; ++ if (temp2 > 0x09) temp2 = 0x09; ++ *(pByte+1) = (cmsUInt8Number)(temp1 | temp2); ++ *(pByte+2) = (cmsUInt8Number)0; ++ *(pByte+3) = (cmsUInt8Number)0; ++ ++ return DWord; ++} ++ + // Read profile header and validate it + cmsBool _cmsReadHeader(_cmsICCPROFILE* Icc) + { +@@ -657,7 +683,7 @@ + Icc -> creator = _cmsAdjustEndianess32(Header.creator); + + _cmsAdjustEndianess64(&Icc -> attributes, &Header.attributes); +- Icc -> Version = _cmsAdjustEndianess32(Header.version); ++ Icc -> Version = _cmsAdjustEndianess32(_validatedVersion(Header.version)); + + // Get size as reported in header + HeaderSize = _cmsAdjustEndianess32(Header.size); +--- a/src/cmsio1.c ++++ b/src/cmsio1.c +@@ -906,7 +906,7 @@ + { + if (!cmsWriteTag(hProfile, cmsSigProfileSequenceDescTag, seq)) return FALSE; + +- if (cmsGetProfileVersion(hProfile) >= 4.0) { ++ if (cmsGetEncodedICCversion(hProfile) >= 0x4000000) { + + if (!cmsWriteTag(hProfile, cmsSigProfileSequenceIdTag, seq)) return FALSE; + } +--- a/src/cmsplugin.c ++++ b/src/cmsplugin.c +@@ -932,8 +932,8 @@ + + // Search for previous + for (prev = _cmsContextPoolHead; +- prev != NULL; +- prev = prev ->Next) ++ prev != NULL; ++ prev = prev ->Next) + { + if (prev -> Next == ctx) { + prev -> Next = ctx ->Next; +--- a/src/cmsvirt.c ++++ b/src/cmsvirt.c +@@ -642,7 +642,7 @@ + // Create the ICC virtual profile for sRGB space + cmsHPROFILE CMSEXPORT cmsCreate_sRGBProfileTHR(cmsContext ContextID) + { +- cmsCIExyY D65; ++ cmsCIExyY D65 = { 0.3127, 0.3290, 1.0 }; + cmsCIExyYTRIPLE Rec709Primaries = { + {0.6400, 0.3300, 1.0}, + {0.3000, 0.6000, 1.0}, diff -Nru lcms2-2.5/debian/patches/series lcms2-2.6/debian/patches/series --- lcms2-2.5/debian/patches/series 2014-01-16 05:44:16.000000000 +0000 +++ lcms2-2.6/debian/patches/series 2014-06-23 09:17:06.000000000 +0000 @@ -1,6 +1,7 @@ -tificc.1 -jpgicc.1 -config-updates.diff -powerpc64le.patch +fix-cmsnamed-alignment-issue.patch +update-manpages.patch +prepare-for-libtoolizing.patch +sanity-check-profiles-CVE-2014-0459.patch +fix-unaligned-access.patch +endianness-verification-fix-powerpc.patch byte-order.patch -fix-floating-point-rounding-in-version-numbers.diff diff -Nru lcms2-2.5/debian/patches/tificc.1 lcms2-2.6/debian/patches/tificc.1 --- lcms2-2.5/debian/patches/tificc.1 2012-11-29 21:24:05.000000000 +0000 +++ lcms2-2.6/debian/patches/tificc.1 1970-01-01 00:00:00.000000000 +0000 @@ -1,11 +0,0 @@ ---- lcms2-2.1.orig/utils/tificc/tificc.1 -+++ lcms2-2.1/utils/tificc/tificc.1 -@@ -49,7 +49,7 @@ - Soft proof profile. - .TP - .BI \-o\ profile --.p -+.TP - Output profile (defaults to sRGB). - .TP - .BI \-s\ profile diff -Nru lcms2-2.5/debian/patches/update-manpages.patch lcms2-2.6/debian/patches/update-manpages.patch --- lcms2-2.5/debian/patches/update-manpages.patch 1970-01-01 00:00:00.000000000 +0000 +++ lcms2-2.6/debian/patches/update-manpages.patch 2014-06-19 12:01:14.000000000 +0000 @@ -0,0 +1,665 @@ +Description: Update manpages to 2.5 release +Author: Thomas Weber +Bug-Debian: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=742587 +Forwarded: yes +--- +This patch header follows DEP-3: http://dep.debian.net/deps/dep3/ +--- a/utils/tificc/tificc.1 ++++ b/utils/tificc/tificc.1 +@@ -1,25 +1,29 @@ + .\"Shiju P. Nair September 30, 2004 +-.TH TIFFICC 1 "October 23, 2004" +-.SH NAME +-tifficc - little cms ICC profile applier for TIFF. ++.\"Thomas Weber April 23, 2014 ++.TH TIFICC 1 "October 23, 2004" ++.SH NAME ++tificc - little cms ICC profile applier for TIFF. + .SH SYNOPSIS +-.B tifficc ++.B tificc + .RI [ options ] " input.tif output.tif" + .SH DESCRIPTION + lcms is a standalone CMM engine, which deals with the color management. + It implements a fast transformation between ICC profiles. +-.B tifficc +-is little cms ICC profile applier for TIFF. ++.B tificc ++is a little cms ICC profile applier for TIFF. + .SH OPTIONS + .TP + .B \-a + Handle channels > 4 as alpha. + .TP +-.B \-b ++.B \-b + Black point compensation. + .TP +-.B \-c <0,1,2,3> +-Precalculates transform. (0=Off, 1=Normal, 2=Hi-res, 3=LoRes) [defaults to 1] ++.BI \-c\ NUM ++Precalculates transform (0=Off, 1=Normal, 2=Hi-res, 3=LoRes) [defaults to 1]. ++.TP ++.BI \-d\ NUM ++Observer adaptation state (abs.col. only), (0..1.0, float value) [defaults to 0.0]. + .TP + .B \-e + Embed destination profile. +@@ -27,74 +31,87 @@ + .B \-g + Marks out-of-gamut colors on softproof. + .TP +-.B \-h <0,1,2> +-Show summary of options and examples. ++.BI \-h\ NUM ++Show summary of options and examples (0=help, 1=Examples, 2=Built-in profiles, 3=Contact information) + .TP + .BI \-i\ profile + Input profile (defaults to sRGB). + .TP +-.B -k <0..400> +-Ink-limiting in % (CMYK only). ++.BI \-k\ inklimit ++Ink-limiting in % (CMYK only), (0..400.0, float value) [default 400.0]. + .TP + .BI \-l\ profile + Transform by device-link profile. + .TP +-.B \-m <0,1,2,3> +-SoftProof intent. ++.B \-m TODO: check if values outside 0..3 are possible ++SoftProof intent [defaults to 0]. + .TP + .B \-n + Ignore embedded profile on input. + .TP +-.BI \-p\ profile +-Soft proof profile. +-.TP + .BI \-o\ profile +-.p + Output profile (defaults to sRGB). + .TP +-.BI \-s\ profile +-Save embedded profile as ++.BI \-p\ profile ++Soft proof profile. ++.TP ++.BI \-s\ newprofile ++Save embedded profile as \fInewprofile\fR. + .TP +-.B \-t <0,1,2,3> +-Intent (0=Perceptual, 1=Colorimetric, 2=Saturation, 3=Absolute). ++.BI \-t\ NUM ++Rendering intent ++.nf ++.RS ++0=Perceptual [default] ++1=Relative colorimetric ++2=Saturation ++3=Absolute colorimetric ++10=Perceptual preserving black ink ++11=Relative colorimetric preserving black ink ++12=Saturation preserving black ink ++13=Perceptual preserving black plane ++14=Relative colorimetric preserving black plane ++15=Saturation preserving black plane ++.RE ++.fi + .TP + .B \-v + Verbose. + .TP +-.B \-w +-Wide output (generates 16 bps tiff). +-.TP +-You can also use following builtins +-*Lab - CIE Lab D50 based +-*XYZ - XYZ +-*adobe1998RBB - AdobeRGB +-*colormatchrgb - ColorMatch RGB +-*applergb - Apple RGB ++.BI \-w\ NUM ++Output depth (8, 16 or 32). Use 32 for floating-point. ++.SH BUILT-IN PROFILES ++.nf ++ *Lab2 -- D50-based v2 CIEL*a*b ++ *Lab4 -- D50-based v4 CIEL*a*b ++ *Lab -- D50-based v4 CIEL*a*b ++ *XYZ -- CIE XYZ (PCS) ++ *sRGB -- sRGB color space ++ *Gray22 - Monochrome of Gamma 2.2 ++ *Gray30 - Monochrome of Gamma 3.0 ++ *null - Monochrome black for all input ++ *Lin2222- CMYK linearization of gamma 2.2 on each channel ++.fi + .SH EXAMPLES + .nf + To color correct from scanner to sRGB: +- tifficc -iscanner.icm in.tif out.tif +- ++ tificc -iscanner.icm in.tif out.tif + To convert from monitor1 to monitor2: +- tifficc -imon1.icm -omon2.icm in.tif out.tif +- ++ tificc -imon1.icm -omon2.icm in.tif out.tif + To make a CMYK separation: +- tifficc -oprinter.icm inrgb.tif outcmyk.tif +- ++ tificc -oprinter.icm inrgb.tif outcmyk.tif + To recover sRGB from a CMYK separation: +- tifficc -iprinter.icm incmyk.tif outrgb.tif +- ++ tificc -iprinter.icm incmyk.tif outrgb.tif + To convert from CIELab TIFF to sRGB +- tifficc -iTiffLab8Spac.icm in.tif out.tif +-.fi ++ tificc -i*Lab in.tif out.tif ++.fi + .SH NOTES + For suggestions, comments, bug reports etc. send mail to info@littlecms.com. + .SH SEE ALSO +-.BR jpegicc (1), +-.BR icc2ps (1), +-.BR icclink (1), +-.BR icctrans (1), +-.BR wtpt (1) ++.BR jpgicc (1), ++.BR linkicc (1), ++.BR psicc (1), ++.BR transicc (1) + .SH AUTHOR + This manual page was originally written by Shiju p. Nair , + for the Debian project. Modified by Marti Maria to reflect further changes. +--- a/utils/jpgicc/jpgicc.1 ++++ b/utils/jpgicc/jpgicc.1 +@@ -1,79 +1,122 @@ + .\"Shiju P. Nair September 30, 2004 +-.TH JPEGICC 1 "September 30, 2004" ++.\"Thomas Weber April 23, 2014 ++.TH JPGICC 1 "September 30, 2004" + .SH NAME +-jpegicc - little cms ICC profile applier for JPEG. ++jpgicc - little cms ICC profile applier for JPEG. + .SH SYNOPSIS +-.B jpegicc ++.B jpgicc + .RI [ options ] " input.jpg output.jpg" + .SH DESCRIPTION + lcms is a standalone CMM engine, which deals with the color management. + It implements a fast transformation between ICC profiles. +-.B jpegicc +-is little cms ICC profile applier for JPEG. ++.B jpgicc ++is a little cms ICC profile applier for JPEG. + .SH OPTIONS + .TP +-.B \-b ++.B \-b + Black point compensation. +-.TP +-.B \-c <0,1,2,3> +-Precalculates transform. (0=Off, 1=Normal, 2=Hi-res, 3=LoRes) [defaults to 1] ++.TP ++.BI \-c\ NUM ++Precalculates transform (0=Off, 1=Normal, 2=Hi-res, 3=LoRes) [defaults to 1]. ++.TP ++.BI \-d\ NUM ++Observer adaptation state (abs.col. only), (0..1.0, float value) [defaults to 0.0]. ++.TP ++.B \-e ++Embed destination profile. + .TP + .B \-g + Marks out-of-gamut colors on softproof. + .TP +-.B \-h <0,1,2> +-Show summary of options and examples. ++.BI \-h\ NUM ++Show summary of options and examples (0=help, 1=Examples, 2=Built-in profiles, 3=Contact information) + .TP + .BI \-i\ profile + Input profile (defaults to sRGB). + .TP +-.B \-m <0,1,2,3> +-SoftProof intent. ++.BI \-l\ link ++TODO: explain this option. ++.TP ++.BI \-m\ NUM ++SoftProof intent (0,1,2,3) [defaults to 0]. + .TP + .B \-n + Ignore embedded profile. + .TP +-.BI \-p\ profile +-Soft proof profile +-.TP + .BI \-o\ profile +-.p + Output profile (defaults to sRGB). + .TP +-.B \-q <0..100> +-Output JPEG quality. ++.BI \-p\ profile ++Soft proof profile. ++.TP ++.BI \-q\ NUM ++Output JPEG quality, (0..100) [defaults to 75]. + .TP +-.B \-t <0,1,2,3> +-Intent (0=Perceptual, 1=Colorimetric, 2=Saturation, 3=Absolute). ++.BI \-s\ newprofile ++Save embedded profile as \fInewprofile\fR. ++.TP ++.BI \-t\ NUM ++Rendering intent ++.nf ++.RS ++0=Perceptual [default] ++1=Relative colorimetric ++2=Saturation ++3=Absolute colorimetric ++10=Perceptual preserving black ink ++11=Relative colorimetric preserving black ink ++12=Saturation preserving black ink ++13=Perceptual preserving black plane ++14=Relative colorimetric preserving black plane ++15=Saturation preserving black plane ++.RE ++.fi + .TP + .B \-v + Verbose. ++.TP ++.BI \-!\ NUM,NUM,NUM ++Out-of-gamut marker channel values (r,g,b) [defaults: 128,128,128]. ++.SH BUILT-IN PROFILES ++.nf ++ *Lab2 -- D50-based v2 CIEL*a*b ++ *Lab4 -- D50-based v4 CIEL*a*b ++ *Lab -- D50-based v4 CIEL*a*b ++ *XYZ -- CIE XYZ (PCS) ++ *sRGB -- sRGB color space ++ *Gray22 - Monochrome of Gamma 2.2 ++ *Gray30 - Monochrome of Gamma 3.0 ++ *null - Monochrome black for all input ++ *Lin2222- CMYK linearization of gamma 2.2 on each channel ++.fi + .SH EXAMPLES + .nf + To color correct from scanner to sRGB: +- jpegicc -iscanner.icm in.jpg out.jpg +- ++ jpgicc -iscanner.icm in.jpg out.jpg ++ + To convert from monitor1 to monitor2: +- jpegicc -imon1.icm -omon2.icm in.jpg out.jpg ++ jpgicc -imon1.icm -omon2.icm in.jpg out.jpg + + To make a CMYK separation: +- jpegicc -oprinter.icm inrgb.jpg outcmyk.jpg ++ jpgicc -oprinter.icm inrgb.jpg outcmyk.jpg + + To recover sRGB from a CMYK separation: +- jpegicc -iprinter.icm incmyk.jpg outrgb.jpg ++ jpgicc -iprinter.icm incmyk.jpg outrgb.jpg ++ ++To convert from CIELab ITU/Fax JPEG to sRGB ++ jpgicc -iitufax.icm in.jpg out.jpg + + To convert from CIELab ITU/Fax JPEG to sRGB +- jpegicc -iitufax.icm in.jpg out.jpg +-.fi ++ jpgicc in.jpg out.jpg ++.fi + .SH NOTES + For suggestions, comments, bug reports etc. send mail to + info@littlecms.com. + .SH SEE ALSO +-.BR tifficc (1), +-.BR icc2ps (1), +-.BR icclink (1), +-.BR icctrans (1), +-.BR wtpt (1) ++.BR linkicc (1), ++.BR psicc (1), ++.BR tificc (1), ++.BR transicc (1) + .SH AUTHOR + This manual page was written by Shiju p. Nair , + for the Debian project. +--- a/utils/linkicc/linkicc.1 ++++ b/utils/linkicc/linkicc.1 +@@ -1,90 +1,123 @@ + .\"Shiju P. Nair September 30, 2004 +-.TH ICCLINK 1 "September 30, 2004" ++.\"Thomas Weber April 23, 2014 ++.TH LINKICC 1 "September 30, 2004" + .SH NAME +-icclink - little cms device link generator. ++linkicc - little cms device link generator. + .SH SYNOPSIS +-.B icclink +-.RI [ options ] " " ++.B linkicc ++.RI [ options ] " profiles" + .SH DESCRIPTION + lcms is a standalone CMM engine, which deals with the color management. + It implements a fast transformation between ICC profiles. +-.B icclink +-is little cms device link generator. ++.B linkicc ++is a little cms device link generator. + .P + Links two or more profiles into a single devicelink profile. + Colorspaces must be paired except Lab/XYZ, that can be interchanged. + .SH OPTIONS + .TP +-.B \-8 +-Creates 8-bit devicelink. ++.BR \-a\ NUM ++Observer adaptation state (abs.col. only), (0..1.0, float value) [defaults to 1.0]. + .TP +-.B \-b ++.B \-b + Black point compensation. + .TP +-.B \-c <0,1,2,3> +-Precision (0=LowRes, 1=Normal, 2=Hi-res). [defaults to 1] ++.BI \-c\ precision ++Precision (0=LowRes, 1=Normal, 2=Hi-res) [defaults to 1]. + .TP + .BI \-d\ description + Description text (quotes can be used). + .TP +-.B \-h <0,1,2,3> +-Show summary of options and examples. ++.BI \-h\ NUM ++Show summary of options and examples (0=help, 1=Built-in profiles, 2=Examples, 3=Contact information) ++.TP ++.BI \-k\ inklimit ++Ink-limiting in % (CMYK only), (0..400.0, float value) [default 400.0]. + .TP +-.BI \-i\ profile +-Input profile (defaults to sRGB). ++.B \-l ++Use linearization curves (may affect accuracy). + .TP +-.B -k <0..400> +-Ink-limiting in % (CMYK only) ++.BI \-n\ gridpoints ++Alternate way to set precision, number of CLUT points. + .TP + .BI \-o\ profile +-Output devicelink profile. [defaults to 'devicelink.icm'] ++Output devicelink profile [defaults to 'devicelink.icm']. ++.TP ++.BI \-r\ profileversion ++Profile version. (CAUTION: may change the profile implementation), (2.0..4.3, float value) [defaults to 4.3]. ++.TP ++.BI \-t\ NUM ++Rendering intent ++.nf ++.RS ++0=Perceptual [default] ++1=Relative colorimetric ++2=Saturation ++3=Absolute colorimetric ++10=Perceptual preserving black ink ++11=Relative colorimetric preserving black ink ++12=Saturation preserving black ink ++13=Perceptual preserving black plane ++14=Relative colorimetric preserving black plane ++15=Saturation preserving black plane ++.RE ++.fi + .TP +-.B \-t <0,1,2,3> +-Intent (0=Perceptual, 1=Colorimetric, 2=Saturation, 3=Absolute). ++.BI \-v\ verbosity ++Verbosity level, (0=None, 1=Normal, 2=High, 3=Very High) [defaults to 0]. + .TP +-.B \-x ++.B \-x + Creatively, guess deviceclass of resulting profile. + .TP ++.BI \-y\ copyright ++Copyright notice (quotes can be used) ["No copyright, use freely"]. ++.TP ++.B \-8 ++Creates 8-bit devicelink. ++.SH BUILT-IN PROFILES + .nf +-Built-in profiles: +- *Lab -- D50-based CIEL*a*b (PCS) +- *XYZ -- CIE XYZ (PCS) +- *sRGB -- sRGB color space +- *Gray22- Monochrome of Gamma 2.2 ++ *Lab2 -- D50-based v2 CIEL*a*b ++ *Lab4 -- D50-based v4 CIEL*a*b ++ *Lab -- D50-based v4 CIEL*a*b ++ *XYZ -- CIE XYZ (PCS) ++ *sRGB -- sRGB color space ++ *Gray22 - Monochrome of Gamma 2.2 ++ *Gray30 - Monochrome of Gamma 3.0 ++ *null - Monochrome black for all input + *Lin2222- CMYK linearization of gamma 2.2 on each channel +-.fi ++.fi + .SH EXAMPLES + .nf + To create 'devicelink.icm' from a.icc to b.icc: +- icclink a.icc b.icc ++ linkicc a.icc b.icc + + To create 'out.icc' from sRGB to cmyk.icc: +- icclink -o out.icc *sRGB cmyk.icc ++ linkicc -o out.icc *sRGB cmyk.icc + + To create a sRGB input profile working in Lab: +- icclink -x -o sRGBLab.icc *sRGB *Lab ++ linkicc -x -o sRGBLab.icc *sRGB *Lab + + To create a XYZ -> sRGB output profile: +- icclink -x -o sRGBLab.icc *XYZ *sRGB ++ linkicc -x -o sRGBLab.icc *XYZ *sRGB + + To create a abstract profile doing softproof for cmyk.icc: +- icclink -t1 -x -o softproof.icc *Lab cmyk.icc cmyk.icc *Lab ++ linkicc -t1 -x -o softproof.icc *Lab cmyk.icc cmyk.icc *Lab + + To create a 'grayer' sRGB input profile: +- icclink -x -o grayer.icc *sRGB gray.icc gray.icc *Lab ++ linkicc -x -o grayer.icc *sRGB gray.icc gray.icc *Lab + + To embed ink limiting into a cmyk output profile: +- icclink -x -o cmyklimited.icc -k 250 cmyk.icc *Lab ++ linkicc -x -o cmyklimited.icc -k 250 cmyk.icc *Lab ++ + .fi + .SH NOTES + For suggestions, comments, bug reports etc. send mail to + info@littlecms.com. + .SH SEE ALSO +-.BR jpegicc (1), +-.BR tifficc (1), +-.BR icc2ps (1), +-.BR icctrans (1), +-.BR wtpt (1) ++.BR jpgicc (1), ++.BR psicc (1), ++.BR tificc (1), ++.BR transicc (1) + .SH AUTHOR + This manual page was written by Shiju p. Nair , + for the Debian project. +--- a/utils/psicc/psicc.1 ++++ b/utils/psicc/psicc.1 +@@ -1,41 +1,47 @@ + .\"Shiju P. Nair September 30, 2004 +-.TH ICC2PS 1 "September 30, 2004" ++.\"Thomas Weber April 23, 2014 ++.TH PSICC 1 "September 30, 2004" + .SH NAME +-icc2ps - little cms PostScript converter. ++psicc - little cms PostScript converter. + .SH SYNOPSIS +-.B icc2ps ++.B psicc + .RI [ options ] + .SH DESCRIPTION + lcms is a standalone CMM engine, which deals with the color management. + It implements a fast transformation between ICC profiles. +-.B icc2ps +-is little cms PostScript converter. ++.B psicc ++is a little cms PostScript converter. + .SH OPTIONS + .TP +-.B \-b ++.B \-b + Black point compensation (CRD only). + .TP ++.BI \-c\ precision ++Precision (0=LowRes, 1=Normal, 2=Hi-res) (CRD only) [defaults to 1]. ++.TP + .BI \-i\ profile + Input profile: Generates Color Space Array (CSA). + .TP ++.BI \-n\ gridpoints ++Alternate way to set precision, number of CLUT points (CRD only). ++.TP + .BI \-o\ profile + .p + Output profile: Generates Color Rendering Dictionary(CRD). + .TP +-.B \-t <0,1,2,3> +-Intent (0=Perceptual, 1=Colorimetric, 2=Saturation, 3=Absolute). ++.BI \-t\ intent ++Intent (0=Perceptual, 1=Colorimetric, 2=Saturation, 3=Absolute) [defaults to 0]. + .TP +-.B \-u ++.B \-u + Do NOT generate resource name on CRD. + .SH NOTES + For suggestions, comments, bug reports etc. send mail to + info@littlecms.com. + .SH SEE ALSO +-.BR jpegicc (1), +-.BR tifficc (1), +-.BR icclink (1), +-.BR icctrans (1), +-.BR wtpt (1) ++.BR jpgicc (1), ++.BR linkicc (1), ++.BR tificc (1), ++.BR transicc (1) + .SH AUTHOR + This manual page was written by Shiju p. Nair , + for the Debian project. +--- a/utils/transicc/transicc.1 ++++ b/utils/transicc/transicc.1 +@@ -1,25 +1,32 @@ + .\"Shiju P. Nair September 30, 2004 ++.\"Thomas Weber April 23, 2014 + .TH TRANSICC 1 "MAY 30, 2011" + .SH NAME +-icctrans - little cms ColorSpace conversion calculator. ++transicc - little cms ColorSpace conversion calculator. + .SH SYNOPSIS +-.B icctrans +-.RI [ options ] ++.B transicc ++.RI [ options ]\ [ CGATSINPUT ]\ [ CGATSOUTPUT ] + .SH DESCRIPTION + lcms is a standalone CMM engine, which deals with the color management. + It implements a fast transformation between ICC profiles. +-.B icctrans +-is lcms ColorSpace conversion calculator. ++.B transicc ++is a lcms ColorSpace conversion calculator. + .SH OPTIONS + .TP +-.B \-% +-use percent % of ink. +-.TP +-.B \-b ++.B \-b + Black point compensation. + .TP +-.B \-c <0,1,2,3> +-Precalculates transform. (0=Off, 1=Normal, 2=Hi-res, 3=LoRes) [defaults to 1] ++.BI \-c\ NUM ++Precalculates transform (0=Off, 1=Normal, 2=Hi-res, 3=LoRes) [defaults to 1]. ++.TP ++.BI \-d\ NUM ++Observer adaptation state (abs.col. only), (0..1.0, float value) [defaults to 0.0]. ++.TP ++.B \-e ++Encoded representation of numbers is not float (Option \fB\-w\fR=use 16 bits, Option \fB\-x\fR=hexadecimal). ++.TP ++.B \-g ++Marks out-of-gamut colors on softproof. + .TP + .BI \-i\ profile + Input profile (defaults to sRGB). +@@ -27,6 +34,9 @@ + .B \-l + Transform by device-link profile. + .TP ++.BI \-m\ NUM ++SoftProof intent (0,1,2,3) [defaults to 0]. ++.TP + .B \-n + Terse output, intended for pipe usage. + .TP +@@ -34,11 +44,28 @@ + .p + Output profile (defaults to sRGB). + .TP +-.B \-t <0,1,2,3> +-Intent (0=Perceptual, 1=Colorimetric, 2=Saturation, 3=Absolute). ++.B \-q ++Quantize CGATS to 8 bits. ++.TP ++.BI \-t\ NUM ++Rendering intent ++.nf ++.RS ++0=Perceptual [default] ++1=Relative colorimetric ++2=Saturation ++3=Absolute colorimetric ++10=Perceptual preserving black ink ++11=Relative colorimetric preserving black ink ++12=Saturation preserving black ink ++13=Perceptual preserving black plane ++14=Relative colorimetric preserving black plane ++15=Saturation preserving black plane ++.RE ++.fi + .TP +-.B \-v +-Verbose. ++.BI \-v\ verbosity ++Verbosity level, (0=None, 1=Normal, 2=High, 3=Very High) [defaults to 1]. + .TP + .B \-w + Use 16 bits. +@@ -51,11 +78,10 @@ + For suggestions, comments, bug reports etc. send mail to + info@littlecms.com. + .SH SEE ALSO +-.BR jpegicc (1), +-.BR tifficc (1), +-.BR icc2ps (1), +-.BR icclink (1), +-.BR wtpt (1) ++.BR jpgicc (1), ++.BR linkicc (1), ++.BR psicc (1), ++.BR tificc (1) + .SH AUTHOR + This manual page was written by Shiju p. Nair , + for the Debian project. diff -Nru lcms2-2.5/debian/rules lcms2-2.6/debian/rules --- lcms2-2.5/debian/rules 2013-12-11 11:13:22.000000000 +0000 +++ lcms2-2.6/debian/rules 2014-06-19 12:01:13.000000000 +0000 @@ -8,13 +8,10 @@ # Uncomment this to turn on verbose mode. export DH_VERBOSE=1 -include /usr/share/quilt/quilt.make - -override_dh_auto_configure: - dh_auto_configure -- \ - --libdir=/usr/lib/$(shell dpkg-architecture -qDEB_HOST_MULTIARCH) - -#override_dh_auto_test: %: - dh $@ --with autotools_dev + dh $@ --with autoreconf + +.PHONY: override_dh_strip +override_dh_strip: + dh_strip --dbg-package=liblcms2-dbg diff -Nru lcms2-2.5/debian/source/include-binaries lcms2-2.6/debian/source/include-binaries --- lcms2-2.5/debian/source/include-binaries 1970-01-01 00:00:00.000000000 +0000 +++ lcms2-2.6/debian/source/include-binaries 2014-06-19 12:01:14.000000000 +0000 @@ -0,0 +1 @@ +doc/src.zip diff -Nru lcms2-2.5/debian/watch lcms2-2.6/debian/watch --- lcms2-2.5/debian/watch 2012-11-29 21:24:05.000000000 +0000 +++ lcms2-2.6/debian/watch 2014-06-19 12:01:14.000000000 +0000 @@ -1,8 +1,3 @@ -# Example watch control file for uscan -# Rename this file to "watch" and then you can run the "uscan" command -# to check for upstream updates and more. -# See uscan(1) for format - # Compulsory line, this is a version 3 file version=3 Binary files /tmp/PwkAlo6nzi/lcms2-2.5/doc/LittleCMS2.5 API.pdf and /tmp/bYaH4ACarr/lcms2-2.6/doc/LittleCMS2.5 API.pdf differ Binary files /tmp/PwkAlo6nzi/lcms2-2.5/doc/LittleCMS2.5 Plugin API.pdf and /tmp/bYaH4ACarr/lcms2-2.6/doc/LittleCMS2.5 Plugin API.pdf differ Binary files /tmp/PwkAlo6nzi/lcms2-2.5/doc/LittleCMS2.5 tutorial.pdf and /tmp/bYaH4ACarr/lcms2-2.6/doc/LittleCMS2.5 tutorial.pdf differ Binary files /tmp/PwkAlo6nzi/lcms2-2.5/doc/LittleCMS2.6 API.pdf and /tmp/bYaH4ACarr/lcms2-2.6/doc/LittleCMS2.6 API.pdf differ Binary files /tmp/PwkAlo6nzi/lcms2-2.5/doc/LittleCMS2.6 Plugin API.pdf and /tmp/bYaH4ACarr/lcms2-2.6/doc/LittleCMS2.6 Plugin API.pdf differ Binary files /tmp/PwkAlo6nzi/lcms2-2.5/doc/LittleCMS2.6 tutorial.pdf and /tmp/bYaH4ACarr/lcms2-2.6/doc/LittleCMS2.6 tutorial.pdf differ Binary files /tmp/PwkAlo6nzi/lcms2-2.5/doc/src.zip and /tmp/bYaH4ACarr/lcms2-2.6/doc/src.zip differ diff -Nru lcms2-2.5/include/lcms2.h lcms2-2.6/include/lcms2.h --- lcms2-2.5/include/lcms2.h 2013-06-27 16:01:28.000000000 +0000 +++ lcms2-2.6/include/lcms2.h 2014-03-17 16:09:30.000000000 +0000 @@ -1,7 +1,7 @@ //--------------------------------------------------------------------------------- // // Little Color Management System -// Copyright (c) 1998-2013 Marti Maria Saguer +// Copyright (c) 1998-2014 Marti Maria Saguer // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the "Software"), @@ -23,7 +23,7 @@ // //--------------------------------------------------------------------------------- // -// Version 2.5 +// Version 2.6 // #ifndef _lcms2_H @@ -55,6 +55,9 @@ // Uncomment to get rid of the tables for "half" float support // #define CMS_NO_HALF_SUPPORT 1 +// Uncomment to get rid of pthreads/windows dependency +// #define CMS_NO_PTHREADS 1 + // ********** End of configuration toggles ****************************** // Needed for streams @@ -72,7 +75,7 @@ #endif // Version/release -#define LCMS_VERSION 2050 +#define LCMS_VERSION 2060 // I will give the chance of redefining basic types for compilers that are not fully C99 compliant #ifndef CMS_BASIC_TYPES_ALREADY_DEFINED @@ -173,28 +176,42 @@ // Try to detect big endian platforms. This list can be endless, so only some checks are performed over here. // you can pass this toggle to the compiler by using -DCMS_USE_BIG_ENDIAN or something similar -#if defined(_HOST_BIG_ENDIAN) || defined(__BIG_ENDIAN__) || defined(WORDS_BIGENDIAN) +#if defined(__sgi__) || defined(__sgi) || defined(sparc) # define CMS_USE_BIG_ENDIAN 1 #endif -#if defined(__sgi__) || defined(__sgi) || defined(__powerpc__) || defined(sparc) -# define CMS_USE_BIG_ENDIAN 1 +#if defined(__s390__) || defined(__s390x__) +# define CMS_USE_BIG_ENDIAN 1 #endif -#if defined(__ppc__) || defined(__s390__) || defined(__s390x__) +# ifdef TARGET_CPU_PPC +# if TARGET_CPU_PPC +# define CMS_USE_BIG_ENDIAN 1 +# endif +# endif + +#if defined(__powerpc__) || defined(__ppc__) || defined(TARGET_CPU_PPC) # define CMS_USE_BIG_ENDIAN 1 +# if defined (__GNUC__) && defined(__BYTE_ORDER) && defined(__LITTLE_ENDIAN) +# if __BYTE_ORDER == __LITTLE_ENDIAN +// // Don't use big endian for PowerPC little endian mode +# undef CMS_USE_BIG_ENDIAN +# endif +# endif #endif -#ifdef TARGET_CPU_PPC -# if TARGET_CPU_PPC -# define CMS_USE_BIG_ENDIAN 1 -# endif +// WORDS_BIGENDIAN takes precedence +#if defined(_HOST_BIG_ENDIAN) || defined(__BIG_ENDIAN__) || defined(WORDS_BIGENDIAN) +# define CMS_USE_BIG_ENDIAN 1 #endif #ifdef macintosh # ifdef __BIG_ENDIAN__ # define CMS_USE_BIG_ENDIAN 1 # endif +# ifdef __LITTLE_ENDIAN__ +# undef CMS_USE_BIG_ENDIAN +# endif #endif // Calling convention -- this is hardly platform and compiler dependent @@ -220,6 +237,14 @@ # define CMSAPI #endif +#ifdef HasTHREADS +# if HasTHREADS == 1 +# undef CMS_NO_PTHREADS +# else +# define CMS_NO_PTHREADS 1 +# endif +#endif + // Some common definitions #define cmsMAX_PATH 256 @@ -613,7 +638,6 @@ // Little CMS specific typedefs -typedef void* cmsContext; // Context identifier for multithreaded environments typedef void* cmsHANDLE ; // Generic handle typedef void* cmsHPROFILE; // Opaque typedefs to hide internals typedef void* cmsHTRANSFORM; @@ -983,11 +1007,25 @@ CMSAPI int CMSEXPORT cmsstrcasecmp(const char* s1, const char* s2); CMSAPI long int CMSEXPORT cmsfilelength(FILE* f); -// Plug-In registering --------------------------------------------------------------------------------------------------- + +// Context handling -------------------------------------------------------------------------------------------------------- + +// Each context holds its owns globals and its own plug-ins. There is a global context with the id = 0 for lecacy compatibility +// though using the global context is not recomended. Proper context handling makes lcms more thread-safe. + +typedef struct _cmsContext_struct* cmsContext; + +CMSAPI cmsContext CMSEXPORT cmsCreateContext(void* Plugin, void* UserData); +CMSAPI void CMSEXPORT cmsDeleteContext(cmsContext ContexID); +CMSAPI cmsContext CMSEXPORT cmsDupContext(cmsContext ContextID, void* NewUserData); +CMSAPI void* CMSEXPORT cmsGetContextUserData(cmsContext ContextID); + +// Plug-In registering -------------------------------------------------------------------------------------------------- CMSAPI cmsBool CMSEXPORT cmsPlugin(void* Plugin); CMSAPI cmsBool CMSEXPORT cmsPluginTHR(cmsContext ContextID, void* Plugin); CMSAPI void CMSEXPORT cmsUnregisterPlugins(void); +CMSAPI void CMSEXPORT cmsUnregisterPluginsTHR(cmsContext ContextID); // Error logging ---------------------------------------------------------------------------------------------------------- @@ -1024,6 +1062,7 @@ // Allows user to set any specific logger CMSAPI void CMSEXPORT cmsSetLogErrorHandler(cmsLogErrorHandlerFunction Fn); +CMSAPI void CMSEXPORT cmsSetLogErrorHandlerTHR(cmsContext ContextID, cmsLogErrorHandlerFunction Fn); // Conversions -------------------------------------------------------------------------------------------------------------- @@ -1485,6 +1524,7 @@ CMSAPI cmsHPROFILE CMSEXPORT cmsOpenProfileFromMem(const void * MemPtr, cmsUInt32Number dwSize); CMSAPI cmsHPROFILE CMSEXPORT cmsOpenProfileFromMemTHR(cmsContext ContextID, const void * MemPtr, cmsUInt32Number dwSize); CMSAPI cmsHPROFILE CMSEXPORT cmsOpenProfileFromIOhandlerTHR(cmsContext ContextID, cmsIOHANDLER* io); +CMSAPI cmsHPROFILE CMSEXPORT cmsOpenProfileFromIOhandler2THR(cmsContext ContextID, cmsIOHANDLER* io, cmsBool write); CMSAPI cmsBool CMSEXPORT cmsCloseProfile(cmsHPROFILE hProfile); CMSAPI cmsBool CMSEXPORT cmsSaveProfileToFile(cmsHPROFILE hProfile, const char* FileName); @@ -1575,6 +1615,7 @@ // Call with NULL as parameters to get the intent count CMSAPI cmsUInt32Number CMSEXPORT cmsGetSupportedIntents(cmsUInt32Number nMax, cmsUInt32Number* Codes, char** Descriptions); +CMSAPI cmsUInt32Number CMSEXPORT cmsGetSupportedIntentsTHR(cmsContext ContextID, cmsUInt32Number nMax, cmsUInt32Number* Codes, char** Descriptions); // Flags @@ -1686,11 +1727,22 @@ cmsUInt32Number Stride); -CMSAPI void CMSEXPORT cmsSetAlarmCodes(cmsUInt16Number NewAlarm[cmsMAXCHANNELS]); +CMSAPI void CMSEXPORT cmsSetAlarmCodes(const cmsUInt16Number NewAlarm[cmsMAXCHANNELS]); CMSAPI void CMSEXPORT cmsGetAlarmCodes(cmsUInt16Number NewAlarm[cmsMAXCHANNELS]); + +CMSAPI void CMSEXPORT cmsSetAlarmCodesTHR(cmsContext ContextID, + const cmsUInt16Number AlarmCodes[cmsMAXCHANNELS]); +CMSAPI void CMSEXPORT cmsGetAlarmCodesTHR(cmsContext ContextID, + cmsUInt16Number AlarmCodes[cmsMAXCHANNELS]); + + + // Adaptation state for absolute colorimetric intent CMSAPI cmsFloat64Number CMSEXPORT cmsSetAdaptationState(cmsFloat64Number d); +CMSAPI cmsFloat64Number CMSEXPORT cmsSetAdaptationStateTHR(cmsContext ContextID, cmsFloat64Number d); + + // Grab the ContextID from an open transform. Returns NULL if a NULL transform is passed CMSAPI cmsContext CMSEXPORT cmsGetTransformContextID(cmsHTRANSFORM hTransform); diff -Nru lcms2-2.5/include/lcms2_plugin.h lcms2-2.6/include/lcms2_plugin.h --- lcms2-2.5/include/lcms2_plugin.h 2013-06-27 16:01:28.000000000 +0000 +++ lcms2-2.6/include/lcms2_plugin.h 2014-03-17 16:09:30.000000000 +0000 @@ -202,6 +202,7 @@ #define cmsPluginMultiProcessElementSig 0x6D706548 // 'mpeH' #define cmsPluginOptimizationSig 0x6F707448 // 'optH' #define cmsPluginTransformSig 0x7A666D48 // 'xfmH' +#define cmsPluginMutexSig 0x6D747A48 // 'mtxH' typedef struct _cmsPluginBaseStruct { @@ -218,19 +219,28 @@ //---------------------------------------------------------------------------------------------------------- // Memory handler. Each new plug-in type replaces current behaviour + +typedef void* (* _cmsMallocFnPtrType)(cmsContext ContextID, cmsUInt32Number size); +typedef void (* _cmsFreeFnPtrType)(cmsContext ContextID, void *Ptr); +typedef void* (* _cmsReallocFnPtrType)(cmsContext ContextID, void* Ptr, cmsUInt32Number NewSize); + +typedef void* (* _cmsMalloZerocFnPtrType)(cmsContext ContextID, cmsUInt32Number size); +typedef void* (* _cmsCallocFnPtrType)(cmsContext ContextID, cmsUInt32Number num, cmsUInt32Number size); +typedef void* (* _cmsDupFnPtrType)(cmsContext ContextID, const void* Org, cmsUInt32Number size); + typedef struct { cmsPluginBase base; // Required - void * (* MallocPtr)(cmsContext ContextID, cmsUInt32Number size); - void (* FreePtr)(cmsContext ContextID, void *Ptr); - void * (* ReallocPtr)(cmsContext ContextID, void* Ptr, cmsUInt32Number NewSize); + _cmsMallocFnPtrType MallocPtr; + _cmsFreeFnPtrType FreePtr; + _cmsReallocFnPtrType ReallocPtr; // Optional - void * (* MallocZeroPtr)(cmsContext ContextID, cmsUInt32Number size); - void * (* CallocPtr)(cmsContext ContextID, cmsUInt32Number num, cmsUInt32Number size); - void * (* DupPtr)(cmsContext ContextID, const void* Org, cmsUInt32Number size); + _cmsMalloZerocFnPtrType MallocZeroPtr; + _cmsCallocFnPtrType CallocPtr; + _cmsDupFnPtrType DupPtr; } cmsPluginMemHandler; @@ -593,6 +603,29 @@ } cmsPluginTransform; +//---------------------------------------------------------------------------------------------------------- +// Mutex + +typedef void* (* _cmsCreateMutexFnPtrType)(cmsContext ContextID); +typedef void (* _cmsDestroyMutexFnPtrType)(cmsContext ContextID, void* mtx); +typedef cmsBool (* _cmsLockMutexFnPtrType)(cmsContext ContextID, void* mtx); +typedef void (* _cmsUnlockMutexFnPtrType)(cmsContext ContextID, void* mtx); + +typedef struct { + cmsPluginBase base; + + _cmsCreateMutexFnPtrType CreateMutexPtr; + _cmsDestroyMutexFnPtrType DestroyMutexPtr; + _cmsLockMutexFnPtrType LockMutexPtr; + _cmsUnlockMutexFnPtrType UnlockMutexPtr; + +} cmsPluginMutex; + +CMSAPI void* CMSEXPORT _cmsCreateMutex(cmsContext ContextID); +CMSAPI void CMSEXPORT _cmsDestroyMutex(cmsContext ContextID, void* mtx); +CMSAPI cmsBool CMSEXPORT _cmsLockMutex(cmsContext ContextID, void* mtx); +CMSAPI void CMSEXPORT _cmsUnlockMutex(cmsContext ContextID, void* mtx); + #ifndef CMS_USE_CPP_API # ifdef __cplusplus diff -Nru lcms2-2.5/include/Makefile.in lcms2-2.6/include/Makefile.in --- lcms2-2.5/include/Makefile.in 2013-06-27 16:01:28.000000000 +0000 +++ lcms2-2.6/include/Makefile.in 2014-03-17 16:09:30.000000000 +0000 @@ -59,7 +59,8 @@ DIST_COMMON = $(include_HEADERS) $(srcdir)/Makefile.am \ $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/configure.ac +am__aclocal_m4_deps = $(top_srcdir)/m4/acx_pthread.m4 \ + $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d @@ -152,6 +153,7 @@ LIBTOOL_DEPS = @LIBTOOL_DEPS@ LIB_JPEG = @LIB_JPEG@ LIB_MATH = @LIB_MATH@ +LIB_THREAD = @LIB_THREAD@ LIB_TIFF = @LIB_TIFF@ LIB_ZLIB = @LIB_ZLIB@ LIPO = @LIPO@ @@ -175,6 +177,10 @@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ +PTHREAD_CC = @PTHREAD_CC@ +PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ +PTHREAD_CXX = @PTHREAD_CXX@ +PTHREAD_LIBS = @PTHREAD_LIBS@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ @@ -190,6 +196,7 @@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +acx_pthread_config = @acx_pthread_config@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ diff -Nru lcms2-2.5/m4/acx_pthread.m4 lcms2-2.6/m4/acx_pthread.m4 --- lcms2-2.5/m4/acx_pthread.m4 1970-01-01 00:00:00.000000000 +0000 +++ lcms2-2.6/m4/acx_pthread.m4 2014-03-17 16:09:30.000000000 +0000 @@ -0,0 +1,305 @@ +##### http://autoconf-archive.cryp.to/acx_pthread.html +# +# SYNOPSIS +# +# ACX_PTHREAD([ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]]) +# +# DESCRIPTION +# +# This macro figures out how to build C programs using POSIX threads. +# It sets the PTHREAD_LIBS output variable to the threads library and +# linker flags, and the PTHREAD_CFLAGS output variable to any special +# C compiler flags that are needed. (The user can also force certain +# compiler flags/libs to be tested by setting these environment +# variables.) +# +# Also sets PTHREAD_CC to any special C compiler that is needed for +# multi-threaded programs (defaults to the value of CC otherwise). +# (This is necessary on AIX to use the special cc_r compiler alias.) +# +# NOTE: You are assumed to not only compile your program with these +# flags, but also link it with them as well. e.g. you should link +# with $PTHREAD_CC $CFLAGS $PTHREAD_CFLAGS $LDFLAGS ... $PTHREAD_LIBS +# $LIBS +# +# If you are only building threads programs, you may wish to use +# these variables in your default LIBS, CFLAGS, and CC: +# +# LIBS="$PTHREAD_LIBS $LIBS" +# CFLAGS="$CFLAGS $PTHREAD_CFLAGS" +# CC="$PTHREAD_CC" +# +# In addition, if the PTHREAD_CREATE_JOINABLE thread-attribute +# constant has a nonstandard name, defines PTHREAD_CREATE_JOINABLE to +# that name (e.g. PTHREAD_CREATE_UNDETACHED on AIX). +# +# ACTION-IF-FOUND is a list of shell commands to run if a threads +# library is found, and ACTION-IF-NOT-FOUND is a list of commands to +# run it if it is not found. If ACTION-IF-FOUND is not specified, the +# default action will define HAVE_PTHREAD. +# +# Please let the authors know if this macro fails on any platform, or +# if you have any other suggestions or comments. This macro was based +# on work by SGJ on autoconf scripts for FFTW (http://www.fftw.org/) +# (with help from M. Frigo), as well as ac_pthread and hb_pthread +# macros posted by Alejandro Forero Cuervo to the autoconf macro +# repository. We are also grateful for the helpful feedback of +# numerous users. +# +# LAST MODIFICATION +# +# 2006-05-29 +# +# COPYLEFT +# +# Copyright (c) 2006 Steven G. Johnson +# +# 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. +# +# As a special exception, the respective Autoconf Macro's copyright +# owner gives unlimited permission to copy, distribute and modify the +# configure scripts that are the output of Autoconf when processing +# the Macro. You need not follow the terms of the GNU General Public +# License when using or distributing such scripts, even though +# portions of the text of the Macro appear in them. The GNU General +# Public License (GPL) does govern all other use of the material that +# constitutes the Autoconf Macro. +# +# This special exception to the GPL applies to versions of the +# Autoconf Macro released by the Autoconf Macro Archive. When you +# make and distribute a modified version of the Autoconf Macro, you +# may extend this special exception to the GPL to apply to your +# modified version as well. + +AC_DEFUN([ACX_PTHREAD], [ +AC_REQUIRE([AC_CANONICAL_HOST]) +AC_LANG_SAVE +AC_LANG_C +acx_pthread_ok=no + +# We used to check for pthread.h first, but this fails if pthread.h +# requires special compiler flags (e.g. on True64 or Sequent). +# It gets checked for in the link test anyway. + +# First of all, check if the user has set any of the PTHREAD_LIBS, +# etcetera environment variables, and if threads linking works using +# them: +if test x"$PTHREAD_LIBS$PTHREAD_CFLAGS" != x; then + save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" + save_LIBS="$LIBS" + LIBS="$PTHREAD_LIBS $LIBS" + AC_MSG_CHECKING([for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS]) + AC_TRY_LINK_FUNC(pthread_join, acx_pthread_ok=yes) + AC_MSG_RESULT($acx_pthread_ok) + if test x"$acx_pthread_ok" = xno; then + PTHREAD_LIBS="" + PTHREAD_CFLAGS="" + fi + LIBS="$save_LIBS" + CFLAGS="$save_CFLAGS" +fi + +# We must check for the threads library under a number of different +# names; the ordering is very important because some systems +# (e.g. DEC) have both -lpthread and -lpthreads, where one of the +# libraries is broken (non-POSIX). + +# Create a list of thread flags to try. Items starting with a "-" are +# C compiler flags, and other items are library names, except for "none" +# which indicates that we try without any flags at all, and "pthread-config" +# which is a program returning the flags for the Pth emulation library. + +acx_pthread_flags="pthreads none -Kthread -kthread lthread -pthread -pthreads -mthreads pthread --thread-safe -mt lpthread pthread-config" + +# The ordering *is* (sometimes) important. Some notes on the +# individual items follow: + +# pthreads: AIX (must check this before -lpthread) +# none: in case threads are in libc; should be tried before -Kthread and +# other compiler flags to prevent continual compiler warnings +# -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h) +# -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able) +# lthread: LinuxThreads port on FreeBSD (also preferred to -pthread) +# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads) +# -pthreads: Solaris/gcc +# -mthreads: Mingw32/gcc, Lynx/gcc +# -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it +# doesn't hurt to check since this sometimes defines pthreads too; +# also defines -D_REENTRANT) +# ... -mt is also the pthreads flag for HP/aCC +# pthread: Linux, etcetera +# --thread-safe: KAI C++ +# pthread-config: use pthread-config program (for GNU Pth library) + +case "${host_cpu}-${host_os}" in + *solaris*) + + # On Solaris (at least, for some versions), libc contains stubbed + # (non-functional) versions of the pthreads routines, so link-based + # tests will erroneously succeed. (We need to link with -pthreads/-mt/ + # -lpthread.) (The stubs are missing pthread_cleanup_push, or rather + # a function called by this macro, so we could check for that, but + # who knows whether they'll stub that too in a future libc.) So, + # we'll just look for -pthreads and -lpthread first: + + acx_pthread_flags="-pthreads pthread -mt -pthread $acx_pthread_flags" + ;; + + # The HP-UX compiler just warns about options it does not understand + # but it needs -mt. + *-hpux*) + acx_pthread_flags="-mt $acx_pthread_flags" + ;; +esac + +if test x"$acx_pthread_ok" = xno; then +for flag in $acx_pthread_flags; do + + case $flag in + none) + AC_MSG_CHECKING([whether pthreads work without any flags]) + ;; + + -*) + AC_MSG_CHECKING([whether pthreads work with $flag]) + PTHREAD_CFLAGS="$flag" + ;; + + pthread-config) + AC_CHECK_PROG(acx_pthread_config, pthread-config, yes, no) + if test x"$acx_pthread_config" = xno; then continue; fi + PTHREAD_CFLAGS="`pthread-config --cflags`" + PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`" + ;; + + *) + AC_MSG_CHECKING([for the pthreads library -l$flag]) + PTHREAD_LIBS="-l$flag" + ;; + esac + + save_LIBS="$LIBS" + save_CFLAGS="$CFLAGS" + LIBS="$PTHREAD_LIBS $LIBS" + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" + + # Check for various functions. We must include pthread.h, + # since some functions may be macros. (On the Sequent, we + # need a special flag -Kthread to make this header compile.) + # We check for pthread_join because it is in -lpthread on IRIX + # while pthread_create is in libc. We check for pthread_attr_init + # due to DEC craziness with -lpthreads. We check for + # pthread_cleanup_push because it is one of the few pthread + # functions on Solaris that doesn't have a non-functional libc stub. + # We try pthread_create on general principles. + AC_TRY_LINK([#include ], + [pthread_t th; pthread_join(th, 0); + pthread_attr_init(0); pthread_cleanup_push(0, 0); + pthread_create(0,0,0,0); pthread_cleanup_pop(0); ], + [acx_pthread_ok=yes]) + + LIBS="$save_LIBS" + CFLAGS="$save_CFLAGS" + + AC_MSG_RESULT($acx_pthread_ok) + if test "x$acx_pthread_ok" = xyes; then + break; + fi + + PTHREAD_LIBS="" + PTHREAD_CFLAGS="" +done +fi + +# Various other checks: +if test "x$acx_pthread_ok" = xyes; then + save_LIBS="$LIBS" + LIBS="$PTHREAD_LIBS $LIBS" + save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" + + # Detect AIX lossage: JOINABLE attribute is called UNDETACHED. + AC_MSG_CHECKING([for joinable pthread attribute]) + attr_name=unknown + for attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do + AC_TRY_LINK([#include ], [int attr=$attr; return attr;], + [attr_name=$attr; break]) + done + AC_MSG_RESULT($attr_name) + if test "$attr_name" != PTHREAD_CREATE_JOINABLE; then + AC_DEFINE_UNQUOTED(PTHREAD_CREATE_JOINABLE, $attr_name, + [Define to necessary symbol if this constant + uses a non-standard name on your system.]) + fi + + AC_MSG_CHECKING([if more special flags are required for pthreads]) + flag=no + case "${host_cpu}-${host_os}" in + *-aix* | *-freebsd* | *-darwin*) flag="-D_THREAD_SAFE";; + *solaris* | *-osf* | *-hpux*) flag="-D_REENTRANT";; + esac + AC_MSG_RESULT(${flag}) + if test "x$flag" != xno; then + PTHREAD_CFLAGS="$flag $PTHREAD_CFLAGS" + fi + + LIBS="$save_LIBS" + CFLAGS="$save_CFLAGS" + + # More AIX lossage: must compile with xlc_r or cc_r + case "${host_os}" in + aix* ) + if test x"$GCC" != xyes; then + case "$CC" in + *xlc ) + AC_CHECK_PROG(PTHREAD_CC, xlc_r, xlc_r, ${CC}) ;; + *cc ) + AC_CHECK_PROG(PTHREAD_CC, cc_r, cc_r, ${CC}) ;; + esac + fi + case "$CXX" in + *xlC ) + AC_CHECK_PROG(PTHREAD_CXX, xlC_r, xlC_r, ${CXX}) ;; + esac + ;; + esac +fi + +if test "${PTHREAD_CC}x" = "x" +then + PTHREAD_CC="$CC" +fi +if test "${PTHREAD_CXX}x" = "x" +then + PTHREAD_CXX="$CXX" +fi + +AC_SUBST(PTHREAD_LIBS) +AC_SUBST(PTHREAD_CFLAGS) +AC_SUBST(PTHREAD_CC) +AC_SUBST(PTHREAD_CXX) + +# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND: +if test x"$acx_pthread_ok" = xyes; then + ifelse([$1],,AC_DEFINE(HAVE_PTHREAD,1,[Define if you have POSIX threads libraries and header files.]),[$1]) + : +else + acx_pthread_ok=no + $2 +fi +AC_LANG_RESTORE +])dnl ACX_PTHREAD diff -Nru lcms2-2.5/Makefile.am lcms2-2.6/Makefile.am --- lcms2-2.5/Makefile.am 2013-06-27 16:01:28.000000000 +0000 +++ lcms2-2.6/Makefile.am 2014-03-17 16:09:30.000000000 +0000 @@ -5,6 +5,8 @@ # Don't require all the GNU mandated files AUTOMAKE_OPTIONS = 1.7.2 dist-zip foreign +ACLOCAL_AMFLAGS = -I m4 + PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_VERSION = @PACKAGE_VERSION@ @@ -12,7 +14,7 @@ SUBDIRS = src include utils/tificc utils/transicc utils/linkicc utils/jpgicc utils/psicc testbed # Additional files to distribute -EXTRA_DIST = AUTHORS COPYING ChangeLog doc Projects include bin Lib INSTALL README.1ST lcms2.pc.in +EXTRA_DIST = AUTHORS COPYING ChangeLog doc Projects include bin Lib INSTALL README.1ST autogen.sh lcms2.pc.in pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = lcms2.pc diff -Nru lcms2-2.5/Makefile.in lcms2-2.6/Makefile.in --- lcms2-2.5/Makefile.in 2013-06-27 16:01:28.000000000 +0000 +++ lcms2-2.6/Makefile.in 2014-03-17 16:09:30.000000000 +0000 @@ -61,7 +61,8 @@ $(top_srcdir)/configure AUTHORS COPYING ChangeLog INSTALL \ config.guess config.sub depcomp install-sh ltmain.sh missing ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/configure.ac +am__aclocal_m4_deps = $(top_srcdir)/m4/acx_pthread.m4 \ + $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ @@ -208,6 +209,7 @@ LIBTOOL_DEPS = @LIBTOOL_DEPS@ LIB_JPEG = @LIB_JPEG@ LIB_MATH = @LIB_MATH@ +LIB_THREAD = @LIB_THREAD@ LIB_TIFF = @LIB_TIFF@ LIB_ZLIB = @LIB_ZLIB@ LIPO = @LIPO@ @@ -231,6 +233,10 @@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ +PTHREAD_CC = @PTHREAD_CC@ +PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ +PTHREAD_CXX = @PTHREAD_CXX@ +PTHREAD_LIBS = @PTHREAD_LIBS@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ @@ -246,6 +252,7 @@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +acx_pthread_config = @acx_pthread_config@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ @@ -295,12 +302,13 @@ # Don't require all the GNU mandated files AUTOMAKE_OPTIONS = 1.7.2 dist-zip foreign +ACLOCAL_AMFLAGS = -I m4 # Directories containing Makefiles to 'make' SUBDIRS = src include utils/tificc utils/transicc utils/linkicc utils/jpgicc utils/psicc testbed # Additional files to distribute -EXTRA_DIST = AUTHORS COPYING ChangeLog doc Projects include bin Lib INSTALL README.1ST lcms2.pc.in +EXTRA_DIST = AUTHORS COPYING ChangeLog doc Projects include bin Lib INSTALL README.1ST autogen.sh lcms2.pc.in pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = lcms2.pc all: all-recursive Binary files /tmp/PwkAlo6nzi/lcms2-2.5/Projects/mac/.DS_Store and /tmp/bYaH4ACarr/lcms2-2.6/Projects/mac/.DS_Store differ diff -Nru lcms2-2.5/Projects/mac/LittleCMS/Info.plist lcms2-2.6/Projects/mac/LittleCMS/Info.plist --- lcms2-2.5/Projects/mac/LittleCMS/Info.plist 2013-06-27 16:01:28.000000000 +0000 +++ lcms2-2.6/Projects/mac/LittleCMS/Info.plist 2014-03-17 16:09:30.000000000 +0000 @@ -19,7 +19,7 @@ CFBundleSignature lcms CFBundleVersion - 2.4 + 2.6 CSResourcesFileMapped diff -Nru lcms2-2.5/Projects/mac/LittleCMS/LittleCMS.xcodeproj/mariama.mode1v3 lcms2-2.6/Projects/mac/LittleCMS/LittleCMS.xcodeproj/mariama.mode1v3 --- lcms2-2.5/Projects/mac/LittleCMS/LittleCMS.xcodeproj/mariama.mode1v3 2013-06-27 16:01:28.000000000 +0000 +++ lcms2-2.6/Projects/mac/LittleCMS/LittleCMS.xcodeproj/mariama.mode1v3 2014-03-17 16:09:30.000000000 +0000 @@ -319,18 +319,21 @@ 0867D691FE84028FC02AAC07 1C37FBAC04509CD000000102 + 54E6DC8118AE055400445185 + 54E6DC8218AE055400445185 1C37FABC05509CD000000102 E2644B35053B69B200211256 PBXSmartGroupTreeModuleOutlineStateSelectionKey - 7 - 6 + 12 + 10 + 8 PBXSmartGroupTreeModuleOutlineStateVisibleRectKey - {{0, 0}, {389, 946}} + {{0, 0}, {389, 899}} PBXTopSmartGroupGIDs @@ -342,14 +345,14 @@ GeometryConfiguration Frame - {{0, 0}, {406, 964}} + {{0, 0}, {406, 917}} GroupTreeTableConfiguration MainColumn 389 RubberWindowFrame - 145 -306 1537 1005 0 0 1600 1178 + 143 144 1537 958 0 0 1600 1178 Module PBXSmartGroupTreeModule @@ -365,7 +368,7 @@ PBXProjectModuleGUID 1CE0B20306471E060097A5F4 PBXProjectModuleLabel - testcms2.c + TestBed-Info.plist PBXSplitModuleInNavigatorKey Split0 @@ -373,21 +376,19 @@ PBXProjectModuleGUID 1CE0B20406471E060097A5F4 PBXProjectModuleLabel - testcms2.c + TestBed-Info.plist _historyCapacity 0 bookmark - 54C0D5B915A2072100A94CDC + 54E6DC8318AE055400445185 history 546B29DA10AC6B6E0054D33A - 546B29F510AC6C480054D33A - 54DBD07515A206A100180017 + 5479A29618AE035D002E61E4 prevStack 546B29E010AC6B6E0054D33A - 546B29E110AC6B6E0054D33A SplitCount @@ -401,7 +402,7 @@ Frame {{0, 0}, {1126, 0}} RubberWindowFrame - 145 -306 1537 1005 0 0 1600 1178 + 143 144 1537 958 0 0 1600 1178 Module PBXNavigatorGroup @@ -421,7 +422,7 @@ Frame {{0, 5}, {1126, 959}} RubberWindowFrame - 145 -306 1537 1005 0 0 1600 1178 + 143 144 1537 958 0 0 1600 1178 Module XCDetailModule @@ -445,9 +446,9 @@ TableOfContents - 54C0D5B315A206F900A94CDC + 54E6DC8418AE055400445185 1CE0B1FE06471DED0097A5F4 - 54C0D5B415A206F900A94CDC + 54E6DC8518AE055400445185 1CE0B20306471E060097A5F4 1CE0B20506471E060097A5F4 @@ -566,7 +567,7 @@ StatusbarIsVisible TimeStamp - 362940193.69248402 + 414057556.32574099 ToolbarDisplayMode 1 ToolbarIsVisible @@ -581,11 +582,10 @@ 5 WindowOrderList - 546B297610AC61DD0054D33A - /Users/mariama/lcms2-2.4/Projects/mac/LittleCMS/LittleCMS.xcodeproj + /Users/mariama/lcms2-2.6rc0/Projects/mac/LittleCMS/LittleCMS.xcodeproj WindowString - 145 -306 1537 1005 0 0 1600 1178 + 143 144 1537 958 0 0 1600 1178 WindowToolsV3 @@ -606,7 +606,7 @@ PBXProjectModuleGUID 1CD0528F0623707200166675 PBXProjectModuleLabel - + <No Editor> StatusBarVisibility @@ -615,7 +615,7 @@ Frame {{0, 0}, {897, 417}} RubberWindowFrame - 645 215 897 912 0 0 1600 1178 + 645 255 897 912 0 0 1600 1178 Module PBXNavigatorGroup @@ -641,7 +641,7 @@ Frame {{0, 422}, {897, 449}} RubberWindowFrame - 645 215 897 912 0 0 1600 1178 + 645 255 897 912 0 0 1600 1178 Module PBXBuildResultsModule @@ -664,14 +664,14 @@ TableOfContents 546B297610AC61DD0054D33A - 54C0D5B815A2071B00A94CDC + 5479A28718AE031A002E61E4 1CD0528F0623707200166675 XCMainBuildResultsModuleGUID ToolbarConfiguration xcode.toolbar.config.buildV3 WindowString - 645 215 897 912 0 0 1600 1178 + 645 255 897 912 0 0 1600 1178 WindowToolGUID 546B297610AC61DD0054D33A WindowToolIsVisible @@ -706,8 +706,8 @@ yes sizes - {{0, 0}, {316, 185}} - {{316, 0}, {378, 185}} + {{0, 0}, {316, 194}} + {{316, 0}, {378, 194}} VerticalSplitView @@ -722,8 +722,8 @@ yes sizes - {{0, 0}, {694, 185}} - {{0, 185}, {694, 196}} + {{0, 0}, {694, 194}} + {{0, 194}, {694, 187}} @@ -756,7 +756,7 @@ 148 Frame - {{316, 0}, {378, 185}} + {{316, 0}, {378, 194}} RubberWindowFrame 406 715 694 422 0 0 1600 1178 @@ -784,13 +784,13 @@ TableOfContents 1CD10A99069EF8BA00B06720 - 546B29C910AC6A970054D33A + 5479A28818AE031A002E61E4 1C162984064C10D400B95A72 - 546B29CA10AC6A970054D33A - 546B29CB10AC6A970054D33A - 546B29CC10AC6A970054D33A - 546B29CD10AC6A970054D33A - 546B29CE10AC6A970054D33A + 5479A28918AE031A002E61E4 + 5479A28A18AE031A002E61E4 + 5479A28B18AE031A002E61E4 + 5479A28C18AE031A002E61E4 + 5479A28D18AE031A002E61E4 ToolbarConfiguration xcode.toolbar.config.debugV3 @@ -917,8 +917,6 @@ Dock - BecomeActive - ContentConfiguration PBXProjectModuleGUID @@ -954,7 +952,7 @@ TableOfContents 1C78EAAD065D492600B07095 - 546B29CF10AC6A970054D33A + 5479A28E18AE031A002E61E4 1C78EAAC065D492600B07095 ToolbarConfiguration diff -Nru lcms2-2.5/Projects/mac/LittleCMS/LittleCMS.xcodeproj/mariama.pbxuser lcms2-2.6/Projects/mac/LittleCMS/LittleCMS.xcodeproj/mariama.pbxuser --- lcms2-2.5/Projects/mac/LittleCMS/LittleCMS.xcodeproj/mariama.pbxuser 2013-06-27 16:01:28.000000000 +0000 +++ lcms2-2.6/Projects/mac/LittleCMS/LittleCMS.xcodeproj/mariama.pbxuser 2014-03-17 16:09:30.000000000 +0000 @@ -4,7 +4,7 @@ activeArchitecture = ppc; activeBuildConfigurationName = Release; activeExecutable = 546B29A410AC677E0054D33A /* testbed */; - activeTarget = 8D07F2BC0486CC7A007CD1D0 /* LittleCMS */; + activeTarget = 546B29A210AC677E0054D33A /* testbed */; addToTargets = ( 546B29A210AC677E0054D33A /* testbed */, ); @@ -151,18 +151,14 @@ PBXFileDataSource_Warnings_ColumnID, ); }; - PBXPerProjectTemplateStateSaveDate = 362940143; - PBXWorkspaceStateSaveDate = 362940143; + PBXPerProjectTemplateStateSaveDate = 414057556; + PBXWorkspaceStateSaveDate = 414057556; }; perUserProjectItems = { - 546B29DA10AC6B6E0054D33A = 546B29DA10AC6B6E0054D33A /* PBXTextBookmark */; - 546B29E010AC6B6E0054D33A = 546B29E010AC6B6E0054D33A /* PBXTextBookmark */; - 546B29E110AC6B6E0054D33A = 546B29E110AC6B6E0054D33A /* PBXTextBookmark */; - 546B29E210AC6B6E0054D33A = 546B29E210AC6B6E0054D33A /* PBXTextBookmark */; - 546B29F510AC6C480054D33A = 546B29F510AC6C480054D33A /* PBXTextBookmark */; - 54C0D5B215A206F900A94CDC /* PBXTextBookmark */ = 54C0D5B215A206F900A94CDC /* PBXTextBookmark */; - 54C0D5B915A2072100A94CDC /* PBXTextBookmark */ = 54C0D5B915A2072100A94CDC /* PBXTextBookmark */; - 54DBD07515A206A100180017 = 54DBD07515A206A100180017 /* PBXTextBookmark */; + 546B29DA10AC6B6E0054D33A /* PBXTextBookmark */ = 546B29DA10AC6B6E0054D33A /* PBXTextBookmark */; + 546B29E010AC6B6E0054D33A /* PBXTextBookmark */ = 546B29E010AC6B6E0054D33A /* PBXTextBookmark */; + 5479A29618AE035D002E61E4 /* PBXTextBookmark */ = 5479A29618AE035D002E61E4 /* PBXTextBookmark */; + 54E6DC8318AE055400445185 /* PBXTextBookmark */ = 54E6DC8318AE055400445185 /* PBXTextBookmark */; }; sourceControlManager = 546B292F10AC5E210054D33A /* Source Control */; userBuildSettings = { @@ -188,9 +184,9 @@ }; 546B296B10AC5EAA0054D33A /* TestBed-Info.plist */ = { uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {1128, 522}}"; - sepNavSelRange = "{172, 5}"; - sepNavVisRange = "{0, 671}"; + sepNavIntBoundsRect = "{{0, 0}, {1065, 336}}"; + sepNavSelRange = "{0, 0}"; + sepNavVisRange = "{0, 0}"; }; }; 546B299D10AC672A0054D33A /* RunUnitTests */ = { @@ -236,7 +232,7 @@ }; 546B29AD10AC68410054D33A /* testcms2.c */ = { uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {1065, 110054}}"; + sepNavIntBoundsRect = "{{0, 0}, {1065, 116032}}"; sepNavSelRange = "{0, 0}"; sepNavVisRange = "{0, 0}"; sepNavWindowFrame = "{{61, 247}, {1099, 884}}"; @@ -262,60 +258,20 @@ vrLen = 172; vrLoc = 9140; }; - 546B29E110AC6B6E0054D33A /* PBXTextBookmark */ = { + 5479A29618AE035D002E61E4 /* PBXTextBookmark */ = { isa = PBXTextBookmark; fRef = 546B296B10AC5EAA0054D33A /* TestBed-Info.plist */; name = "TestBed-Info.plist: 1"; rLen = 0; rLoc = 0; rType = 0; - vrLen = 662; - vrLoc = 0; - }; - 546B29E210AC6B6E0054D33A /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - fRef = 546B29AD10AC68410054D33A /* testcms2.c */; - name = "testcms2.c: 1"; - rLen = 0; - rLoc = 0; - rType = 0; - vrLen = 1115; - vrLoc = 0; - }; - 546B29F510AC6C480054D33A /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - fRef = 546B296B10AC5EAA0054D33A /* TestBed-Info.plist */; - name = "TestBed-Info.plist: 5"; - rLen = 5; - rLoc = 172; - rType = 0; - vrLen = 671; - vrLoc = 0; - }; - 54C0D5B215A206F900A94CDC /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - fRef = 546B29AD10AC68410054D33A /* testcms2.c */; - name = "testcms2.c: 1"; - rLen = 0; - rLoc = 0; - rType = 0; - vrLen = 0; - vrLoc = 0; - }; - 54C0D5B915A2072100A94CDC /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - fRef = 546B29AD10AC68410054D33A /* testcms2.c */; - name = "testcms2.c: 1"; - rLen = 0; - rLoc = 0; - rType = 0; vrLen = 0; vrLoc = 0; }; - 54DBD07515A206A100180017 /* PBXTextBookmark */ = { + 54E6DC8318AE055400445185 /* PBXTextBookmark */ = { isa = PBXTextBookmark; - fRef = 546B29AD10AC68410054D33A /* testcms2.c */; - name = "testcms2.c: 1"; + fRef = 546B296B10AC5EAA0054D33A /* TestBed-Info.plist */; + name = "TestBed-Info.plist: 1"; rLen = 0; rLoc = 0; rType = 0; diff -Nru lcms2-2.5/Projects/mac/LittleCMS/LittleCMS.xcodeproj/project.pbxproj lcms2-2.6/Projects/mac/LittleCMS/LittleCMS.xcodeproj/project.pbxproj --- lcms2-2.5/Projects/mac/LittleCMS/LittleCMS.xcodeproj/project.pbxproj 2013-06-27 16:01:28.000000000 +0000 +++ lcms2-2.6/Projects/mac/LittleCMS/LittleCMS.xcodeproj/project.pbxproj 2014-03-17 16:09:30.000000000 +0000 @@ -34,8 +34,9 @@ 546B296310AC5E600054D33A /* lcms2.h in Headers */ = {isa = PBXBuildFile; fileRef = 546B296110AC5E600054D33A /* lcms2.h */; settings = {ATTRIBUTES = (Public, ); }; }; 546B296410AC5E600054D33A /* lcms2_plugin.h in Headers */ = {isa = PBXBuildFile; fileRef = 546B296210AC5E600054D33A /* lcms2_plugin.h */; settings = {ATTRIBUTES = (Public, ); }; }; 546B29AE10AC68410054D33A /* testcms2.c in Sources */ = {isa = PBXBuildFile; fileRef = 546B29AD10AC68410054D33A /* testcms2.c */; }; - 54DBD06115A202B200180017 /* cmshalf.c in Sources */ = {isa = PBXBuildFile; fileRef = 54DBD06015A202B200180017 /* cmshalf.c */; }; 54DBD06215A202BB00180017 /* cmshalf.c in Sources */ = {isa = PBXBuildFile; fileRef = 54DBD06015A202B200180017 /* cmshalf.c */; }; + 54E6DC7E18AE052800445185 /* testplugin.c in Sources */ = {isa = PBXBuildFile; fileRef = 54E6DC7D18AE052800445185 /* testplugin.c */; }; + 54E6DC8018AE054800445185 /* zoo_icc.c in Sources */ = {isa = PBXBuildFile; fileRef = 54E6DC7F18AE054800445185 /* zoo_icc.c */; }; 8D07F2BE0486CC7A007CD1D0 /* LittleCMS_Prefix.pch in Headers */ = {isa = PBXBuildFile; fileRef = 32BAE0B70371A74B00C91783 /* LittleCMS_Prefix.pch */; settings = {ATTRIBUTES = (Private, ); }; }; 8D07F2C00486CC7A007CD1D0 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 089C1666FE841158C02AAC07 /* InfoPlist.strings */; }; 8D07F2C40486CC7A007CD1D0 /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 08FB77AAFE841565C02AAC07 /* Carbon.framework */; }; @@ -86,6 +87,8 @@ 546B29AC10AC682F0054D33A /* lcms2_internal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = lcms2_internal.h; path = ../../../src/lcms2_internal.h; sourceTree = SOURCE_ROOT; }; 546B29AD10AC68410054D33A /* testcms2.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = testcms2.c; path = ../../../testbed/testcms2.c; sourceTree = SOURCE_ROOT; }; 54DBD06015A202B200180017 /* cmshalf.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = cmshalf.c; path = ../../../src/cmshalf.c; sourceTree = ""; }; + 54E6DC7D18AE052800445185 /* testplugin.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = testplugin.c; path = ../../../testbed/testplugin.c; sourceTree = SOURCE_ROOT; }; + 54E6DC7F18AE054800445185 /* zoo_icc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = zoo_icc.c; path = ../../../testbed/zoo_icc.c; sourceTree = SOURCE_ROOT; }; 8D07F2C70486CC7A007CD1D0 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist; path = Info.plist; sourceTree = ""; }; 8D07F2C80486CC7A007CD1D0 /* LittleCMS.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = LittleCMS.framework; sourceTree = BUILT_PRODUCTS_DIR; }; /* End PBXFileReference section */ @@ -121,6 +124,8 @@ 0867D691FE84028FC02AAC07 /* LittleCMS */ = { isa = PBXGroup; children = ( + 54E6DC7F18AE054800445185 /* zoo_icc.c */, + 54E6DC7D18AE052800445185 /* testplugin.c */, 08FB77ACFE841707C02AAC07 /* Source */, 089C1665FE841158C02AAC07 /* Resources */, 0867D69AFE84028FC02AAC07 /* External Frameworks and Libraries */, @@ -283,7 +288,8 @@ buildActionMask = 2147483647; files = ( 546B29AE10AC68410054D33A /* testcms2.c in Sources */, - 54DBD06115A202B200180017 /* cmshalf.c in Sources */, + 54E6DC7E18AE052800445185 /* testplugin.c in Sources */, + 54E6DC8018AE054800445185 /* zoo_icc.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff -Nru lcms2-2.5/Projects/VC2010/testbed/testbed.vcxproj lcms2-2.6/Projects/VC2010/testbed/testbed.vcxproj --- lcms2-2.5/Projects/VC2010/testbed/testbed.vcxproj 2013-06-27 16:01:28.000000000 +0000 +++ lcms2-2.6/Projects/VC2010/testbed/testbed.vcxproj 2014-03-17 16:09:30.000000000 +0000 @@ -189,6 +189,11 @@ + + + + + diff -Nru lcms2-2.5/Projects/VC2010/testbed/testbed.vcxproj.filters lcms2-2.6/Projects/VC2010/testbed/testbed.vcxproj.filters --- lcms2-2.5/Projects/VC2010/testbed/testbed.vcxproj.filters 2013-06-27 16:01:28.000000000 +0000 +++ lcms2-2.6/Projects/VC2010/testbed/testbed.vcxproj.filters 2014-03-17 16:09:30.000000000 +0000 @@ -18,5 +18,16 @@ Source Files + + Source Files + + + Source Files + + + + + Header Files + \ No newline at end of file diff -Nru lcms2-2.5/Projects/VC2012/testbed/testbed.vcxproj lcms2-2.6/Projects/VC2012/testbed/testbed.vcxproj --- lcms2-2.5/Projects/VC2012/testbed/testbed.vcxproj 2013-06-27 16:01:28.000000000 +0000 +++ lcms2-2.6/Projects/VC2012/testbed/testbed.vcxproj 2014-03-17 16:09:30.000000000 +0000 @@ -198,6 +198,8 @@ + + diff -Nru lcms2-2.5/Projects/VC2012/testbed/testbed.vcxproj.filters lcms2-2.6/Projects/VC2012/testbed/testbed.vcxproj.filters --- lcms2-2.5/Projects/VC2012/testbed/testbed.vcxproj.filters 2013-06-27 16:01:28.000000000 +0000 +++ lcms2-2.6/Projects/VC2012/testbed/testbed.vcxproj.filters 2014-03-17 16:09:30.000000000 +0000 @@ -18,5 +18,11 @@ Source Files + + Source Files + + + Source Files + \ No newline at end of file diff -Nru lcms2-2.5/src/cmscam02.c lcms2-2.6/src/cmscam02.c --- lcms2-2.5/src/cmscam02.c 2013-06-27 16:01:28.000000000 +0000 +++ lcms2-2.6/src/cmscam02.c 2014-03-17 16:09:30.000000000 +0000 @@ -437,11 +437,13 @@ { CAM02COLOR clr; cmsCIECAM02* lpMod = (cmsCIECAM02*) hModel; - + _cmsAssert(lpMod != NULL); _cmsAssert(pIn != NULL); _cmsAssert(pOut != NULL); + memset(&clr, 0, sizeof(clr)); + clr.XYZ[0] = pIn ->X; clr.XYZ[1] = pIn ->Y; clr.XYZ[2] = pIn ->Z; @@ -461,11 +463,13 @@ { CAM02COLOR clr; cmsCIECAM02* lpMod = (cmsCIECAM02*) hModel; - + _cmsAssert(lpMod != NULL); _cmsAssert(pIn != NULL); _cmsAssert(pOut != NULL); + memset(&clr, 0, sizeof(clr)); + clr.J = pIn -> J; clr.C = pIn -> C; clr.h = pIn -> h; @@ -480,4 +484,3 @@ pOut ->Y = clr.XYZ[1]; pOut ->Z = clr.XYZ[2]; } - diff -Nru lcms2-2.5/src/cmscgats.c lcms2-2.6/src/cmscgats.c --- lcms2-2.5/src/cmscgats.c 2013-06-27 16:01:28.000000000 +0000 +++ lcms2-2.6/src/cmscgats.c 2014-03-17 16:09:30.000000000 +0000 @@ -2150,9 +2150,9 @@ if (cmsstrcasecmp(Fld, "SAMPLE_ID") == 0) { - t -> SampleID = idField; + t -> SampleID = idField; - for (i=0; i < t -> nPatches; i++) { + for (i=0; i < t -> nPatches; i++) { char *Data = GetData(it8, i, idField); if (Data) { @@ -2167,7 +2167,7 @@ SetData(it8, i, idField, Buffer); } - } + } } diff -Nru lcms2-2.5/src/cmscnvrt.c lcms2-2.6/src/cmscnvrt.c --- lcms2-2.5/src/cmscnvrt.c 2013-06-27 16:01:28.000000000 +0000 +++ lcms2-2.6/src/cmscnvrt.c 2014-03-17 16:09:30.000000000 +0000 @@ -108,15 +108,68 @@ // A pointer to the begining of the list -static cmsIntentsList *Intents = DefaultIntents; +_cmsIntentsPluginChunkType _cmsIntentsPluginChunk = { NULL }; + +// Duplicates the zone of memory used by the plug-in in the new context +static +void DupPluginIntentsList(struct _cmsContext_struct* ctx, + const struct _cmsContext_struct* src) +{ + _cmsIntentsPluginChunkType newHead = { NULL }; + cmsIntentsList* entry; + cmsIntentsList* Anterior = NULL; + _cmsIntentsPluginChunkType* head = (_cmsIntentsPluginChunkType*) src->chunks[IntentPlugin]; + + // Walk the list copying all nodes + for (entry = head->Intents; + entry != NULL; + entry = entry ->Next) { + + cmsIntentsList *newEntry = ( cmsIntentsList *) _cmsSubAllocDup(ctx ->MemPool, entry, sizeof(cmsIntentsList)); + + if (newEntry == NULL) + return; + + // We want to keep the linked list order, so this is a little bit tricky + newEntry -> Next = NULL; + if (Anterior) + Anterior -> Next = newEntry; + + Anterior = newEntry; + + if (newHead.Intents == NULL) + newHead.Intents = newEntry; + } + + ctx ->chunks[IntentPlugin] = _cmsSubAllocDup(ctx->MemPool, &newHead, sizeof(_cmsIntentsPluginChunkType)); +} + +void _cmsAllocIntentsPluginChunk(struct _cmsContext_struct* ctx, + const struct _cmsContext_struct* src) +{ + if (src != NULL) { + + // Copy all linked list + DupPluginIntentsList(ctx, src); + } + else { + static _cmsIntentsPluginChunkType IntentsPluginChunkType = { NULL }; + ctx ->chunks[IntentPlugin] = _cmsSubAllocDup(ctx ->MemPool, &IntentsPluginChunkType, sizeof(_cmsIntentsPluginChunkType)); + } +} + // Search the list for a suitable intent. Returns NULL if not found static -cmsIntentsList* SearchIntent(cmsUInt32Number Intent) +cmsIntentsList* SearchIntent(cmsContext ContextID, cmsUInt32Number Intent) { + _cmsIntentsPluginChunkType* ctx = ( _cmsIntentsPluginChunkType*) _cmsContextGetClientChunk(ContextID, IntentPlugin); cmsIntentsList* pt; - for (pt = Intents; pt != NULL; pt = pt -> Next) + for (pt = ctx -> Intents; pt != NULL; pt = pt -> Next) + if (pt ->Intent == Intent) return pt; + + for (pt = DefaultIntents; pt != NULL; pt = pt -> Next) if (pt ->Intent == Intent) return pt; return NULL; @@ -571,7 +624,9 @@ // Concatenate to the output LUT if (!cmsPipelineCat(Result, Lut)) goto Error; + cmsPipelineFree(Lut); + Lut = NULL; // Update current space CurrentColorSpace = ColorSpaceOut; @@ -581,7 +636,7 @@ Error: - cmsPipelineFree(Lut); + if (Lut != NULL) cmsPipelineFree(Lut); if (Result != NULL) cmsPipelineFree(Result); return NULL; @@ -1000,7 +1055,7 @@ // this case would present some issues if the custom intent tries to do things like // preserve primaries. This solution is not perfect, but works well on most cases. - Intent = SearchIntent(TheIntents[0]); + Intent = SearchIntent(ContextID, TheIntents[0]); if (Intent == NULL) { cmsSignalError(ContextID, cmsERROR_UNKNOWN_EXTENSION, "Unsupported intent '%d'", TheIntents[0]); return NULL; @@ -1015,12 +1070,14 @@ // Get information about available intents. nMax is the maximum space for the supplied "Codes" // and "Descriptions" the function returns the total number of intents, which may be greater // than nMax, although the matrices are not populated beyond this level. -cmsUInt32Number CMSEXPORT cmsGetSupportedIntents(cmsUInt32Number nMax, cmsUInt32Number* Codes, char** Descriptions) +cmsUInt32Number CMSEXPORT cmsGetSupportedIntentsTHR(cmsContext ContextID, cmsUInt32Number nMax, cmsUInt32Number* Codes, char** Descriptions) { + _cmsIntentsPluginChunkType* ctx = ( _cmsIntentsPluginChunkType*) _cmsContextGetClientChunk(ContextID, IntentPlugin); cmsIntentsList* pt; cmsUInt32Number nIntents; - for (nIntents=0, pt = Intents; pt != NULL; pt = pt -> Next) + + for (nIntents=0, pt = ctx->Intents; pt != NULL; pt = pt -> Next) { if (nIntents < nMax) { if (Codes != NULL) @@ -1033,37 +1090,52 @@ nIntents++; } + for (nIntents=0, pt = DefaultIntents; pt != NULL; pt = pt -> Next) + { + if (nIntents < nMax) { + if (Codes != NULL) + Codes[nIntents] = pt ->Intent; + + if (Descriptions != NULL) + Descriptions[nIntents] = pt ->Description; + } + + nIntents++; + } return nIntents; } +cmsUInt32Number CMSEXPORT cmsGetSupportedIntents(cmsUInt32Number nMax, cmsUInt32Number* Codes, char** Descriptions) +{ + return cmsGetSupportedIntentsTHR(NULL, nMax, Codes, Descriptions); +} + // The plug-in registration. User can add new intents or override default routines cmsBool _cmsRegisterRenderingIntentPlugin(cmsContext id, cmsPluginBase* Data) { + _cmsIntentsPluginChunkType* ctx = ( _cmsIntentsPluginChunkType*) _cmsContextGetClientChunk(id, IntentPlugin); cmsPluginRenderingIntent* Plugin = (cmsPluginRenderingIntent*) Data; cmsIntentsList* fl; - // Do we have to reset the intents? + // Do we have to reset the custom intents? if (Data == NULL) { - Intents = DefaultIntents; - return TRUE; + ctx->Intents = NULL; + return TRUE; } - fl = SearchIntent(Plugin ->Intent); + fl = (cmsIntentsList*) _cmsPluginMalloc(id, sizeof(cmsIntentsList)); + if (fl == NULL) return FALSE; - if (fl == NULL) { - fl = (cmsIntentsList*) _cmsPluginMalloc(id, sizeof(cmsIntentsList)); - if (fl == NULL) return FALSE; - } fl ->Intent = Plugin ->Intent; - strncpy(fl ->Description, Plugin ->Description, 255); - fl ->Description[255] = 0; + strncpy(fl ->Description, Plugin ->Description, sizeof(fl ->Description)-1); + fl ->Description[sizeof(fl ->Description)-1] = 0; fl ->Link = Plugin ->Link; - fl ->Next = Intents; - Intents = fl; + fl ->Next = ctx ->Intents; + ctx ->Intents = fl; return TRUE; } diff -Nru lcms2-2.5/src/cmserr.c lcms2-2.6/src/cmserr.c --- lcms2-2.5/src/cmserr.c 2013-06-27 16:01:28.000000000 +0000 +++ lcms2-2.6/src/cmserr.c 2014-03-17 16:09:30.000000000 +0000 @@ -31,13 +31,14 @@ // compare two strings ignoring case int CMSEXPORT cmsstrcasecmp(const char* s1, const char* s2) { - register const unsigned char *us1 = (const unsigned char *)s1, - *us2 = (const unsigned char *)s2; + register const unsigned char *us1 = (const unsigned char *)s1, + *us2 = (const unsigned char *)s2; - while (toupper(*us1) == toupper(*us2++)) - if (*us1++ == '\0') - return (0); - return (toupper(*us1) - toupper(*--us2)); + while (toupper(*us1) == toupper(*us2++)) + if (*us1++ == '\0') + return 0; + + return (toupper(*us1) - toupper(*--us2)); } // long int because C99 specifies ftell in such way (7.19.9.2) @@ -62,9 +63,8 @@ // // This is the interface to low-level memory management routines. By default a simple // wrapping to malloc/free/realloc is provided, although there is a limit on the max -// amount of memoy that can be reclaimed. This is mostly as a safety feature to -// prevent bogus or malintentionated code to allocate huge blocks that otherwise lcms -// would never need. +// amount of memoy that can be reclaimed. This is mostly as a safety feature to prevent +// bogus or evil code to allocate huge blocks that otherwise lcms would never need. #define MAX_MEMORY_FOR_ALLOC ((cmsUInt32Number)(1024U*1024U*512U)) @@ -74,7 +74,7 @@ // required to be implemented: malloc, realloc and free, although the user may want to // replace the optional mallocZero, calloc and dup as well. -cmsBool _cmsRegisterMemHandlerPlugin(cmsPluginBase* Plugin); +cmsBool _cmsRegisterMemHandlerPlugin(cmsContext ContextID, cmsPluginBase* Plugin); // ********************************************************************************* @@ -114,7 +114,7 @@ cmsUNUSED_PARAMETER(ContextID); } -// The default realloc function. Again it check for exploits. If Ptr is NULL, +// The default realloc function. Again it checks for exploits. If Ptr is NULL, // realloc behaves the same way as malloc and allocates a new block of size bytes. static void* _cmsReallocDefaultFn(cmsContext ContextID, void* Ptr, cmsUInt32Number size) @@ -167,28 +167,73 @@ return mem; } -// Pointers to malloc and _cmsFree functions in current environment -static void * (* MallocPtr)(cmsContext ContextID, cmsUInt32Number size) = _cmsMallocDefaultFn; -static void * (* MallocZeroPtr)(cmsContext ContextID, cmsUInt32Number size) = _cmsMallocZeroDefaultFn; -static void (* FreePtr)(cmsContext ContextID, void *Ptr) = _cmsFreeDefaultFn; -static void * (* ReallocPtr)(cmsContext ContextID, void *Ptr, cmsUInt32Number NewSize) = _cmsReallocDefaultFn; -static void * (* CallocPtr)(cmsContext ContextID, cmsUInt32Number num, cmsUInt32Number size)= _cmsCallocDefaultFn; -static void * (* DupPtr)(cmsContext ContextID, const void* Org, cmsUInt32Number size) = _cmsDupDefaultFn; + +// Pointers to memory manager functions in Context0 +_cmsMemPluginChunkType _cmsMemPluginChunk = { _cmsMallocDefaultFn, _cmsMallocZeroDefaultFn, _cmsFreeDefaultFn, + _cmsReallocDefaultFn, _cmsCallocDefaultFn, _cmsDupDefaultFn + }; + + +// Reset and duplicate memory manager +void _cmsAllocMemPluginChunk(struct _cmsContext_struct* ctx, const struct _cmsContext_struct* src) +{ + _cmsAssert(ctx != NULL); + + if (src != NULL) { + + // Duplicate + ctx ->chunks[MemPlugin] = _cmsSubAllocDup(ctx ->MemPool, src ->chunks[MemPlugin], sizeof(_cmsMemPluginChunkType)); + } + else { + + // To reset it, we use the default allocators, which cannot be overriden + ctx ->chunks[MemPlugin] = &ctx ->DefaultMemoryManager; + } +} + +// Auxiliar to fill memory management functions from plugin (or context 0 defaults) +void _cmsInstallAllocFunctions(cmsPluginMemHandler* Plugin, _cmsMemPluginChunkType* ptr) +{ + if (Plugin == NULL) { + + memcpy(ptr, &_cmsMemPluginChunk, sizeof(_cmsMemPluginChunk)); + } + else { + + ptr ->MallocPtr = Plugin -> MallocPtr; + ptr ->FreePtr = Plugin -> FreePtr; + ptr ->ReallocPtr = Plugin -> ReallocPtr; + + // Make sure we revert to defaults + ptr ->MallocZeroPtr= _cmsMallocZeroDefaultFn; + ptr ->CallocPtr = _cmsCallocDefaultFn; + ptr ->DupPtr = _cmsDupDefaultFn; + + if (Plugin ->MallocZeroPtr != NULL) ptr ->MallocZeroPtr = Plugin -> MallocZeroPtr; + if (Plugin ->CallocPtr != NULL) ptr ->CallocPtr = Plugin -> CallocPtr; + if (Plugin ->DupPtr != NULL) ptr ->DupPtr = Plugin -> DupPtr; + + } +} + // Plug-in replacement entry -cmsBool _cmsRegisterMemHandlerPlugin(cmsPluginBase *Data) +cmsBool _cmsRegisterMemHandlerPlugin(cmsContext ContextID, cmsPluginBase *Data) { - cmsPluginMemHandler* Plugin = (cmsPluginMemHandler*) Data; + cmsPluginMemHandler* Plugin = (cmsPluginMemHandler*) Data; + _cmsMemPluginChunkType* ptr; - // NULL forces to reset to defaults + // NULL forces to reset to defaults. In this special case, the defaults are stored in the context structure. + // Remaining plug-ins does NOT have any copy in the context structure, but this is somehow special as the + // context internal data should be malloce'd by using those functions. if (Data == NULL) { - MallocPtr = _cmsMallocDefaultFn; - MallocZeroPtr= _cmsMallocZeroDefaultFn; - FreePtr = _cmsFreeDefaultFn; - ReallocPtr = _cmsReallocDefaultFn; - CallocPtr = _cmsCallocDefaultFn; - DupPtr = _cmsDupDefaultFn; + struct _cmsContext_struct* ctx = ( struct _cmsContext_struct*) ContextID; + + // Return to the default allocators + if (ContextID != NULL) { + ctx->chunks[MemPlugin] = (void*) &ctx->DefaultMemoryManager; + } return TRUE; } @@ -198,51 +243,56 @@ Plugin -> ReallocPtr == NULL) return FALSE; // Set replacement functions - MallocPtr = Plugin -> MallocPtr; - FreePtr = Plugin -> FreePtr; - ReallocPtr = Plugin -> ReallocPtr; - - if (Plugin ->MallocZeroPtr != NULL) MallocZeroPtr = Plugin ->MallocZeroPtr; - if (Plugin ->CallocPtr != NULL) CallocPtr = Plugin -> CallocPtr; - if (Plugin ->DupPtr != NULL) DupPtr = Plugin -> DupPtr; + ptr = (_cmsMemPluginChunkType*) _cmsContextGetClientChunk(ContextID, MemPlugin); + if (ptr == NULL) + return FALSE; + _cmsInstallAllocFunctions(Plugin, ptr); return TRUE; } // Generic allocate void* CMSEXPORT _cmsMalloc(cmsContext ContextID, cmsUInt32Number size) { - return MallocPtr(ContextID, size); + _cmsMemPluginChunkType* ptr = (_cmsMemPluginChunkType*) _cmsContextGetClientChunk(ContextID, MemPlugin); + return ptr ->MallocPtr(ContextID, size); } // Generic allocate & zero void* CMSEXPORT _cmsMallocZero(cmsContext ContextID, cmsUInt32Number size) { - return MallocZeroPtr(ContextID, size); + _cmsMemPluginChunkType* ptr = (_cmsMemPluginChunkType*) _cmsContextGetClientChunk(ContextID, MemPlugin); + return ptr->MallocZeroPtr(ContextID, size); } // Generic calloc void* CMSEXPORT _cmsCalloc(cmsContext ContextID, cmsUInt32Number num, cmsUInt32Number size) { - return CallocPtr(ContextID, num, size); + _cmsMemPluginChunkType* ptr = (_cmsMemPluginChunkType*) _cmsContextGetClientChunk(ContextID, MemPlugin); + return ptr->CallocPtr(ContextID, num, size); } // Generic reallocate void* CMSEXPORT _cmsRealloc(cmsContext ContextID, void* Ptr, cmsUInt32Number size) { - return ReallocPtr(ContextID, Ptr, size); + _cmsMemPluginChunkType* ptr = (_cmsMemPluginChunkType*) _cmsContextGetClientChunk(ContextID, MemPlugin); + return ptr->ReallocPtr(ContextID, Ptr, size); } // Generic free memory void CMSEXPORT _cmsFree(cmsContext ContextID, void* Ptr) { - if (Ptr != NULL) FreePtr(ContextID, Ptr); + if (Ptr != NULL) { + _cmsMemPluginChunkType* ptr = (_cmsMemPluginChunkType*) _cmsContextGetClientChunk(ContextID, MemPlugin); + ptr ->FreePtr(ContextID, Ptr); + } } // Generic block duplication void* CMSEXPORT _cmsDupMem(cmsContext ContextID, const void* Org, cmsUInt32Number size) { - return DupPtr(ContextID, Org, size); + _cmsMemPluginChunkType* ptr = (_cmsMemPluginChunkType*) _cmsContextGetClientChunk(ContextID, MemPlugin); + return ptr ->DupPtr(ContextID, Org, size); } // ******************************************************************************************** @@ -351,6 +401,26 @@ return (void*) ptr; } +// Duplicate in pool +void* _cmsSubAllocDup(_cmsSubAllocator* s, const void *ptr, cmsUInt32Number size) +{ + void *NewPtr; + + // Dup of null pointer is also NULL + if (ptr == NULL) + return NULL; + + NewPtr = _cmsSubAlloc(s, size); + + if (ptr != NULL && NewPtr != NULL) { + memcpy(NewPtr, ptr, size); + } + + return NewPtr; +} + + + // Error logging ****************************************************************** // There is no error handling at all. When a funtion fails, it returns proper value. @@ -372,8 +442,26 @@ // This is our default log error static void DefaultLogErrorHandlerFunction(cmsContext ContextID, cmsUInt32Number ErrorCode, const char *Text); -// The current handler in actual environment -static cmsLogErrorHandlerFunction LogErrorHandler = DefaultLogErrorHandlerFunction; +// Context0 storage, which is global +_cmsLogErrorChunkType _cmsLogErrorChunk = { DefaultLogErrorHandlerFunction }; + +// Allocates and inits error logger container for a given context. If src is NULL, only initializes the value +// to the default. Otherwise, it duplicates the value. The interface is standard across all context clients +void _cmsAllocLogErrorChunk(struct _cmsContext_struct* ctx, + const struct _cmsContext_struct* src) +{ + static _cmsLogErrorChunkType LogErrorChunk = { DefaultLogErrorHandlerFunction }; + void* from; + + if (src != NULL) { + from = src ->chunks[Logger]; + } + else { + from = &LogErrorChunk; + } + + ctx ->chunks[Logger] = _cmsSubAllocDup(ctx ->MemPool, from, sizeof(_cmsLogErrorChunkType)); +} // The default error logger does nothing. static @@ -387,13 +475,24 @@ cmsUNUSED_PARAMETER(Text); } -// Change log error +// Change log error, context based +void CMSEXPORT cmsSetLogErrorHandlerTHR(cmsContext ContextID, cmsLogErrorHandlerFunction Fn) +{ + _cmsLogErrorChunkType* lhg = (_cmsLogErrorChunkType*) _cmsContextGetClientChunk(ContextID, Logger); + + if (lhg != NULL) { + + if (Fn == NULL) + lhg -> LogErrorHandler = DefaultLogErrorHandlerFunction; + else + lhg -> LogErrorHandler = Fn; + } +} + +// Change log error, legacy void CMSEXPORT cmsSetLogErrorHandler(cmsLogErrorHandlerFunction Fn) { - if (Fn == NULL) - LogErrorHandler = DefaultLogErrorHandlerFunction; - else - LogErrorHandler = Fn; + cmsSetLogErrorHandlerTHR(NULL, Fn); } // Log an error @@ -402,13 +501,18 @@ { va_list args; char Buffer[MAX_ERROR_MESSAGE_LEN]; + _cmsLogErrorChunkType* lhg; + va_start(args, ErrorText); vsnprintf(Buffer, MAX_ERROR_MESSAGE_LEN-1, ErrorText, args); va_end(args); - // Call handler - LogErrorHandler(ContextID, ErrorCode, Buffer); + // Check for the context, if specified go there. If not, go for the global + lhg = (_cmsLogErrorChunkType*) _cmsContextGetClientChunk(ContextID, Logger); + if (lhg ->LogErrorHandler) { + lhg ->LogErrorHandler(ContextID, ErrorCode, Buffer); + } } // Utility function to print signatures @@ -426,3 +530,125 @@ String[4] = 0; } +//-------------------------------------------------------------------------------------------------- + + +static +void* defMtxCreate(cmsContext id) +{ + _cmsMutex* ptr_mutex = (_cmsMutex*) _cmsMalloc(id, sizeof(_cmsMutex)); + _cmsInitMutexPrimitive(ptr_mutex); + return (void*) ptr_mutex; +} + +static +void defMtxDestroy(cmsContext id, void* mtx) +{ + _cmsDestroyMutexPrimitive((_cmsMutex *) mtx); + _cmsFree(id, mtx); +} + +static +cmsBool defMtxLock(cmsContext id, void* mtx) +{ + cmsUNUSED_PARAMETER(id); + return _cmsLockPrimitive((_cmsMutex *) mtx) == 0; +} + +static +void defMtxUnlock(cmsContext id, void* mtx) +{ + cmsUNUSED_PARAMETER(id); + _cmsUnlockPrimitive((_cmsMutex *) mtx); +} + + + +// Pointers to memory manager functions in Context0 +_cmsMutexPluginChunkType _cmsMutexPluginChunk = { defMtxCreate, defMtxDestroy, defMtxLock, defMtxUnlock }; + +// Allocate and init mutex container. +void _cmsAllocMutexPluginChunk(struct _cmsContext_struct* ctx, + const struct _cmsContext_struct* src) +{ + static _cmsMutexPluginChunkType MutexChunk = {defMtxCreate, defMtxDestroy, defMtxLock, defMtxUnlock }; + void* from; + + if (src != NULL) { + from = src ->chunks[MutexPlugin]; + } + else { + from = &MutexChunk; + } + + ctx ->chunks[MutexPlugin] = _cmsSubAllocDup(ctx ->MemPool, from, sizeof(_cmsMutexPluginChunkType)); +} + +// Register new ways to transform +cmsBool _cmsRegisterMutexPlugin(cmsContext ContextID, cmsPluginBase* Data) +{ + cmsPluginMutex* Plugin = (cmsPluginMutex*) Data; + _cmsMutexPluginChunkType* ctx = ( _cmsMutexPluginChunkType*) _cmsContextGetClientChunk(ContextID, MutexPlugin); + + if (Data == NULL) { + + // No lock routines + ctx->CreateMutexPtr = NULL; + ctx->DestroyMutexPtr = NULL; + ctx->LockMutexPtr = NULL; + ctx ->UnlockMutexPtr = NULL; + return TRUE; + } + + // Factory callback is required + if (Plugin ->CreateMutexPtr == NULL || Plugin ->DestroyMutexPtr == NULL || + Plugin ->LockMutexPtr == NULL || Plugin ->UnlockMutexPtr == NULL) return FALSE; + + + ctx->CreateMutexPtr = Plugin->CreateMutexPtr; + ctx->DestroyMutexPtr = Plugin ->DestroyMutexPtr; + ctx ->LockMutexPtr = Plugin ->LockMutexPtr; + ctx ->UnlockMutexPtr = Plugin ->UnlockMutexPtr; + + // All is ok + return TRUE; +} + +// Generic Mutex fns +void* CMSEXPORT _cmsCreateMutex(cmsContext ContextID) +{ + _cmsMutexPluginChunkType* ptr = (_cmsMutexPluginChunkType*) _cmsContextGetClientChunk(ContextID, MutexPlugin); + + if (ptr ->CreateMutexPtr == NULL) return NULL; + + return ptr ->CreateMutexPtr(ContextID); +} + +void CMSEXPORT _cmsDestroyMutex(cmsContext ContextID, void* mtx) +{ + _cmsMutexPluginChunkType* ptr = (_cmsMutexPluginChunkType*) _cmsContextGetClientChunk(ContextID, MutexPlugin); + + if (ptr ->DestroyMutexPtr != NULL) { + + ptr ->DestroyMutexPtr(ContextID, mtx); + } +} + +cmsBool CMSEXPORT _cmsLockMutex(cmsContext ContextID, void* mtx) +{ + _cmsMutexPluginChunkType* ptr = (_cmsMutexPluginChunkType*) _cmsContextGetClientChunk(ContextID, MutexPlugin); + + if (ptr ->LockMutexPtr == NULL) return TRUE; + + return ptr ->LockMutexPtr(ContextID, mtx); +} + +void CMSEXPORT _cmsUnlockMutex(cmsContext ContextID, void* mtx) +{ + _cmsMutexPluginChunkType* ptr = (_cmsMutexPluginChunkType*) _cmsContextGetClientChunk(ContextID, MutexPlugin); + + if (ptr ->UnlockMutexPtr != NULL) { + + ptr ->UnlockMutexPtr(ContextID, mtx); + } +} diff -Nru lcms2-2.5/src/cmsgamma.c lcms2-2.6/src/cmsgamma.c --- lcms2-2.5/src/cmsgamma.c 2013-06-27 16:01:28.000000000 +0000 +++ lcms2-2.6/src/cmsgamma.c 2014-03-17 16:09:30.000000000 +0000 @@ -53,7 +53,6 @@ } _cmsParametricCurvesCollection; - // This is the default (built-in) evaluator static cmsFloat64Number DefaultEvalParametricFn(cmsInt32Number Type, const cmsFloat64Number Params[], cmsFloat64Number R); @@ -66,22 +65,77 @@ NULL // Next in chain }; +// Duplicates the zone of memory used by the plug-in in the new context +static +void DupPluginCurvesList(struct _cmsContext_struct* ctx, + const struct _cmsContext_struct* src) +{ + _cmsCurvesPluginChunkType newHead = { NULL }; + _cmsParametricCurvesCollection* entry; + _cmsParametricCurvesCollection* Anterior = NULL; + _cmsCurvesPluginChunkType* head = (_cmsCurvesPluginChunkType*) src->chunks[CurvesPlugin]; + + _cmsAssert(head != NULL); + + // Walk the list copying all nodes + for (entry = head->ParametricCurves; + entry != NULL; + entry = entry ->Next) { + + _cmsParametricCurvesCollection *newEntry = ( _cmsParametricCurvesCollection *) _cmsSubAllocDup(ctx ->MemPool, entry, sizeof(_cmsParametricCurvesCollection)); + + if (newEntry == NULL) + return; + + // We want to keep the linked list order, so this is a little bit tricky + newEntry -> Next = NULL; + if (Anterior) + Anterior -> Next = newEntry; + + Anterior = newEntry; + + if (newHead.ParametricCurves == NULL) + newHead.ParametricCurves = newEntry; + } + + ctx ->chunks[CurvesPlugin] = _cmsSubAllocDup(ctx->MemPool, &newHead, sizeof(_cmsCurvesPluginChunkType)); +} + +// The allocator have to follow the chain +void _cmsAllocCurvesPluginChunk(struct _cmsContext_struct* ctx, + const struct _cmsContext_struct* src) +{ + _cmsAssert(ctx != NULL); + + if (src != NULL) { + + // Copy all linked list + DupPluginCurvesList(ctx, src); + } + else { + static _cmsCurvesPluginChunkType CurvesPluginChunk = { NULL }; + ctx ->chunks[CurvesPlugin] = _cmsSubAllocDup(ctx ->MemPool, &CurvesPluginChunk, sizeof(_cmsCurvesPluginChunkType)); + } +} + + // The linked list head -static _cmsParametricCurvesCollection* ParametricCurves = &DefaultCurves; +_cmsCurvesPluginChunkType _cmsCurvesPluginChunk = { NULL }; // As a way to install new parametric curves -cmsBool _cmsRegisterParametricCurvesPlugin(cmsContext id, cmsPluginBase* Data) +cmsBool _cmsRegisterParametricCurvesPlugin(cmsContext ContextID, cmsPluginBase* Data) { + _cmsCurvesPluginChunkType* ctx = ( _cmsCurvesPluginChunkType*) _cmsContextGetClientChunk(ContextID, CurvesPlugin); cmsPluginParametricCurves* Plugin = (cmsPluginParametricCurves*) Data; _cmsParametricCurvesCollection* fl; if (Data == NULL) { - ParametricCurves = &DefaultCurves; + ctx -> ParametricCurves = NULL; return TRUE; } - fl = (_cmsParametricCurvesCollection*) _cmsPluginMalloc(id, sizeof(_cmsParametricCurvesCollection)); + fl = (_cmsParametricCurvesCollection*) _cmsPluginMalloc(ContextID, sizeof(_cmsParametricCurvesCollection)); if (fl == NULL) return FALSE; // Copy the parameters @@ -97,8 +151,8 @@ memmove(fl->ParameterCount, Plugin ->ParameterCount, fl->nFunctions * sizeof(cmsUInt32Number)); // Keep linked list - fl ->Next = ParametricCurves; - ParametricCurves = fl; + fl ->Next = ctx->ParametricCurves; + ctx->ParametricCurves = fl; // All is ok return TRUE; @@ -120,12 +174,24 @@ // Search for the collection which contains a specific type static -_cmsParametricCurvesCollection *GetParametricCurveByType(int Type, int* index) +_cmsParametricCurvesCollection *GetParametricCurveByType(cmsContext ContextID, int Type, int* index) { _cmsParametricCurvesCollection* c; int Position; + _cmsCurvesPluginChunkType* ctx = ( _cmsCurvesPluginChunkType*) _cmsContextGetClientChunk(ContextID, CurvesPlugin); - for (c = ParametricCurves; c != NULL; c = c ->Next) { + for (c = ctx->ParametricCurves; c != NULL; c = c ->Next) { + + Position = IsInSet(Type, c); + + if (Position != -1) { + if (index != NULL) + *index = Position; + return c; + } + } + // If none found, revert for defaults + for (c = &DefaultCurves; c != NULL; c = c ->Next) { Position = IsInSet(Type, c); @@ -222,7 +288,7 @@ p ->Segments[i].SampledPoints = NULL; - c = GetParametricCurveByType(Segments[i].Type, NULL); + c = GetParametricCurveByType(ContextID, Segments[i].Type, NULL); if (c != NULL) p ->Evals[i] = c ->Evaluator; } @@ -648,12 +714,12 @@ cmsCurveSegment Seg0; int Pos = 0; cmsUInt32Number size; - _cmsParametricCurvesCollection* c = GetParametricCurveByType(Type, &Pos); + _cmsParametricCurvesCollection* c = GetParametricCurveByType(ContextID, Type, &Pos); _cmsAssert(Params != NULL); if (c == NULL) { - cmsSignalError(ContextID, cmsERROR_UNKNOWN_EXTENSION, "Invalid parametric curve type %d", Type); + cmsSignalError(ContextID, cmsERROR_UNKNOWN_EXTENSION, "Invalid parametric curve type %d", Type); return NULL; } @@ -843,7 +909,10 @@ _cmsAssert(InCurve != NULL); // Try to reverse it analytically whatever possible - if (InCurve ->nSegments == 1 && InCurve ->Segments[0].Type > 0 && InCurve -> Segments[0].Type <= 5) { + + if (InCurve ->nSegments == 1 && InCurve ->Segments[0].Type > 0 && + /* InCurve -> Segments[0].Type <= 5 */ + GetParametricCurveByType(InCurve ->InterpParams->ContextID, InCurve ->Segments[0].Type, NULL) != NULL) { return cmsBuildParametricToneCurve(InCurve ->InterpParams->ContextID, -(InCurve -> Segments[0].Type), diff -Nru lcms2-2.5/src/cmsgmt.c lcms2-2.6/src/cmsgmt.c --- lcms2-2.5/src/cmsgmt.c 2013-06-27 16:01:28.000000000 +0000 +++ lcms2-2.6/src/cmsgmt.c 2014-03-17 16:09:30.000000000 +0000 @@ -1,590 +1,590 @@ -//--------------------------------------------------------------------------------- -// -// Little Color Management System -// Copyright (c) 1998-2012 Marti Maria Saguer -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the Software -// is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO -// THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// -//--------------------------------------------------------------------------------- -// - -#include "lcms2_internal.h" - - -// Auxiliar: append a Lab identity after the given sequence of profiles -// and return the transform. Lab profile is closed, rest of profiles are kept open. -cmsHTRANSFORM _cmsChain2Lab(cmsContext ContextID, - cmsUInt32Number nProfiles, - cmsUInt32Number InputFormat, - cmsUInt32Number OutputFormat, - const cmsUInt32Number Intents[], - const cmsHPROFILE hProfiles[], - const cmsBool BPC[], - const cmsFloat64Number AdaptationStates[], - cmsUInt32Number dwFlags) -{ - cmsHTRANSFORM xform; - cmsHPROFILE hLab; - cmsHPROFILE ProfileList[256]; - cmsBool BPCList[256]; - cmsFloat64Number AdaptationList[256]; - cmsUInt32Number IntentList[256]; - cmsUInt32Number i; - - // This is a rather big number and there is no need of dynamic memory - // since we are adding a profile, 254 + 1 = 255 and this is the limit - if (nProfiles > 254) return NULL; - - // The output space - hLab = cmsCreateLab4ProfileTHR(ContextID, NULL); - if (hLab == NULL) return NULL; - - // Create a copy of parameters - for (i=0; i < nProfiles; i++) { - - ProfileList[i] = hProfiles[i]; - BPCList[i] = BPC[i]; - AdaptationList[i] = AdaptationStates[i]; - IntentList[i] = Intents[i]; - } - - // Place Lab identity at chain's end. - ProfileList[nProfiles] = hLab; - BPCList[nProfiles] = 0; - AdaptationList[nProfiles] = 1.0; - IntentList[nProfiles] = INTENT_RELATIVE_COLORIMETRIC; - - // Create the transform - xform = cmsCreateExtendedTransform(ContextID, nProfiles + 1, ProfileList, - BPCList, - IntentList, - AdaptationList, - NULL, 0, - InputFormat, - OutputFormat, - dwFlags); - - cmsCloseProfile(hLab); - - return xform; -} - - -// Compute K -> L* relationship. Flags may include black point compensation. In this case, -// the relationship is assumed from the profile with BPC to a black point zero. -static -cmsToneCurve* ComputeKToLstar(cmsContext ContextID, - cmsUInt32Number nPoints, - cmsUInt32Number nProfiles, - const cmsUInt32Number Intents[], - const cmsHPROFILE hProfiles[], - const cmsBool BPC[], - const cmsFloat64Number AdaptationStates[], - cmsUInt32Number dwFlags) -{ - cmsToneCurve* out = NULL; - cmsUInt32Number i; - cmsHTRANSFORM xform; - cmsCIELab Lab; - cmsFloat32Number cmyk[4]; - cmsFloat32Number* SampledPoints; - - xform = _cmsChain2Lab(ContextID, nProfiles, TYPE_CMYK_FLT, TYPE_Lab_DBL, Intents, hProfiles, BPC, AdaptationStates, dwFlags); - if (xform == NULL) return NULL; - - SampledPoints = (cmsFloat32Number*) _cmsCalloc(ContextID, nPoints, sizeof(cmsFloat32Number)); - if (SampledPoints == NULL) goto Error; - - for (i=0; i < nPoints; i++) { - - cmyk[0] = 0; - cmyk[1] = 0; - cmyk[2] = 0; - cmyk[3] = (cmsFloat32Number) ((i * 100.0) / (nPoints-1)); - - cmsDoTransform(xform, cmyk, &Lab, 1); - SampledPoints[i]= (cmsFloat32Number) (1.0 - Lab.L / 100.0); // Negate K for easier operation - } - - out = cmsBuildTabulatedToneCurveFloat(ContextID, nPoints, SampledPoints); - -Error: - - cmsDeleteTransform(xform); - if (SampledPoints) _cmsFree(ContextID, SampledPoints); - - return out; -} - - -// Compute Black tone curve on a CMYK -> CMYK transform. This is done by -// using the proof direction on both profiles to find K->L* relationship -// then joining both curves. dwFlags may include black point compensation. -cmsToneCurve* _cmsBuildKToneCurve(cmsContext ContextID, - cmsUInt32Number nPoints, - cmsUInt32Number nProfiles, - const cmsUInt32Number Intents[], - const cmsHPROFILE hProfiles[], - const cmsBool BPC[], - const cmsFloat64Number AdaptationStates[], - cmsUInt32Number dwFlags) -{ - cmsToneCurve *in, *out, *KTone; - - // Make sure CMYK -> CMYK - if (cmsGetColorSpace(hProfiles[0]) != cmsSigCmykData || - cmsGetColorSpace(hProfiles[nProfiles-1])!= cmsSigCmykData) return NULL; - - - // Make sure last is an output profile - if (cmsGetDeviceClass(hProfiles[nProfiles - 1]) != cmsSigOutputClass) return NULL; - - // Create individual curves. BPC works also as each K to L* is - // computed as a BPC to zero black point in case of L* - in = ComputeKToLstar(ContextID, nPoints, nProfiles - 1, Intents, hProfiles, BPC, AdaptationStates, dwFlags); - if (in == NULL) return NULL; - - out = ComputeKToLstar(ContextID, nPoints, 1, - Intents + (nProfiles - 1), - hProfiles + (nProfiles - 1), - BPC + (nProfiles - 1), - AdaptationStates + (nProfiles - 1), - dwFlags); - if (out == NULL) { - cmsFreeToneCurve(in); - return NULL; - } - - // Build the relationship. This effectively limits the maximum accuracy to 16 bits, but - // since this is used on black-preserving LUTs, we are not loosing accuracy in any case - KTone = cmsJoinToneCurve(ContextID, in, out, nPoints); - - // Get rid of components - cmsFreeToneCurve(in); cmsFreeToneCurve(out); - - // Something went wrong... - if (KTone == NULL) return NULL; - - // Make sure it is monotonic - if (!cmsIsToneCurveMonotonic(KTone)) { - cmsFreeToneCurve(KTone); - return NULL; - } - - return KTone; -} - - -// Gamut LUT Creation ----------------------------------------------------------------------------------------- - -// Used by gamut & softproofing - -typedef struct { - - cmsHTRANSFORM hInput; // From whatever input color space. 16 bits to DBL - cmsHTRANSFORM hForward, hReverse; // Transforms going from Lab to colorant and back - cmsFloat64Number Thereshold; // The thereshold after which is considered out of gamut - - } GAMUTCHAIN; - -// This sampler does compute gamut boundaries by comparing original -// values with a transform going back and forth. Values above ERR_THERESHOLD -// of maximum are considered out of gamut. - -#define ERR_THERESHOLD 5 - - -static -int GamutSampler(register const cmsUInt16Number In[], register cmsUInt16Number Out[], register void* Cargo) -{ - GAMUTCHAIN* t = (GAMUTCHAIN* ) Cargo; - cmsCIELab LabIn1, LabOut1; - cmsCIELab LabIn2, LabOut2; - cmsUInt16Number Proof[cmsMAXCHANNELS], Proof2[cmsMAXCHANNELS]; - cmsFloat64Number dE1, dE2, ErrorRatio; - - // Assume in-gamut by default. - ErrorRatio = 1.0; - - // Convert input to Lab - cmsDoTransform(t -> hInput, In, &LabIn1, 1); - - // converts from PCS to colorant. This always - // does return in-gamut values, - cmsDoTransform(t -> hForward, &LabIn1, Proof, 1); - - // Now, do the inverse, from colorant to PCS. - cmsDoTransform(t -> hReverse, Proof, &LabOut1, 1); - - memmove(&LabIn2, &LabOut1, sizeof(cmsCIELab)); - - // Try again, but this time taking Check as input - cmsDoTransform(t -> hForward, &LabOut1, Proof2, 1); - cmsDoTransform(t -> hReverse, Proof2, &LabOut2, 1); - - // Take difference of direct value - dE1 = cmsDeltaE(&LabIn1, &LabOut1); - - // Take difference of converted value - dE2 = cmsDeltaE(&LabIn2, &LabOut2); - - - // if dE1 is small and dE2 is small, value is likely to be in gamut - if (dE1 < t->Thereshold && dE2 < t->Thereshold) - Out[0] = 0; - else { - - // if dE1 is small and dE2 is big, undefined. Assume in gamut - if (dE1 < t->Thereshold && dE2 > t->Thereshold) - Out[0] = 0; - else - // dE1 is big and dE2 is small, clearly out of gamut - if (dE1 > t->Thereshold && dE2 < t->Thereshold) - Out[0] = (cmsUInt16Number) _cmsQuickFloor((dE1 - t->Thereshold) + .5); - else { - - // dE1 is big and dE2 is also big, could be due to perceptual mapping - // so take error ratio - if (dE2 == 0.0) - ErrorRatio = dE1; - else - ErrorRatio = dE1 / dE2; - - if (ErrorRatio > t->Thereshold) - Out[0] = (cmsUInt16Number) _cmsQuickFloor((ErrorRatio - t->Thereshold) + .5); - else - Out[0] = 0; - } - } - - - return TRUE; -} - -// Does compute a gamut LUT going back and forth across pcs -> relativ. colorimetric intent -> pcs -// the dE obtained is then annotated on the LUT. Values truely out of gamut are clipped to dE = 0xFFFE -// and values changed are supposed to be handled by any gamut remapping, so, are out of gamut as well. -// -// **WARNING: This algorithm does assume that gamut remapping algorithms does NOT move in-gamut colors, -// of course, many perceptual and saturation intents does not work in such way, but relativ. ones should. - -cmsPipeline* _cmsCreateGamutCheckPipeline(cmsContext ContextID, - cmsHPROFILE hProfiles[], - cmsBool BPC[], - cmsUInt32Number Intents[], - cmsFloat64Number AdaptationStates[], - cmsUInt32Number nGamutPCSposition, - cmsHPROFILE hGamut) -{ - cmsHPROFILE hLab; - cmsPipeline* Gamut; - cmsStage* CLUT; - cmsUInt32Number dwFormat; - GAMUTCHAIN Chain; - int nChannels, nGridpoints; - cmsColorSpaceSignature ColorSpace; - cmsUInt32Number i; - cmsHPROFILE ProfileList[256]; - cmsBool BPCList[256]; - cmsFloat64Number AdaptationList[256]; - cmsUInt32Number IntentList[256]; - - memset(&Chain, 0, sizeof(GAMUTCHAIN)); - - - if (nGamutPCSposition <= 0 || nGamutPCSposition > 255) { - cmsSignalError(ContextID, cmsERROR_RANGE, "Wrong position of PCS. 1..255 expected, %d found.", nGamutPCSposition); - return NULL; - } - - hLab = cmsCreateLab4ProfileTHR(ContextID, NULL); - if (hLab == NULL) return NULL; - - - // The figure of merit. On matrix-shaper profiles, should be almost zero as - // the conversion is pretty exact. On LUT based profiles, different resolutions - // of input and output CLUT may result in differences. - - if (cmsIsMatrixShaper(hGamut)) { - - Chain.Thereshold = 1.0; - } - else { - Chain.Thereshold = ERR_THERESHOLD; - } - - - // Create a copy of parameters - for (i=0; i < nGamutPCSposition; i++) { - ProfileList[i] = hProfiles[i]; - BPCList[i] = BPC[i]; - AdaptationList[i] = AdaptationStates[i]; - IntentList[i] = Intents[i]; - } - - // Fill Lab identity - ProfileList[nGamutPCSposition] = hLab; - BPCList[nGamutPCSposition] = 0; - AdaptationList[nGamutPCSposition] = 1.0; - IntentList[nGamutPCSposition] = INTENT_RELATIVE_COLORIMETRIC; - - - ColorSpace = cmsGetColorSpace(hGamut); - - nChannels = cmsChannelsOf(ColorSpace); - nGridpoints = _cmsReasonableGridpointsByColorspace(ColorSpace, cmsFLAGS_HIGHRESPRECALC); - dwFormat = (CHANNELS_SH(nChannels)|BYTES_SH(2)); - - // 16 bits to Lab double - Chain.hInput = cmsCreateExtendedTransform(ContextID, - nGamutPCSposition + 1, - ProfileList, - BPCList, - IntentList, - AdaptationList, - NULL, 0, - dwFormat, TYPE_Lab_DBL, - cmsFLAGS_NOCACHE); - - - // Does create the forward step. Lab double to device - dwFormat = (CHANNELS_SH(nChannels)|BYTES_SH(2)); - Chain.hForward = cmsCreateTransformTHR(ContextID, - hLab, TYPE_Lab_DBL, - hGamut, dwFormat, - INTENT_RELATIVE_COLORIMETRIC, - cmsFLAGS_NOCACHE); - - // Does create the backwards step - Chain.hReverse = cmsCreateTransformTHR(ContextID, hGamut, dwFormat, - hLab, TYPE_Lab_DBL, - INTENT_RELATIVE_COLORIMETRIC, - cmsFLAGS_NOCACHE); - - - // All ok? - if (Chain.hInput && Chain.hForward && Chain.hReverse) { - - // Go on, try to compute gamut LUT from PCS. This consist on a single channel containing - // dE when doing a transform back and forth on the colorimetric intent. - - Gamut = cmsPipelineAlloc(ContextID, 3, 1); - if (Gamut != NULL) { - - CLUT = cmsStageAllocCLut16bit(ContextID, nGridpoints, nChannels, 1, NULL); - if (!cmsPipelineInsertStage(Gamut, cmsAT_BEGIN, CLUT)) { - cmsPipelineFree(Gamut); - Gamut = NULL; - } - else { - cmsStageSampleCLut16bit(CLUT, GamutSampler, (void*) &Chain, 0); - } - } - } - else - Gamut = NULL; // Didn't work... - - // Free all needed stuff. - if (Chain.hInput) cmsDeleteTransform(Chain.hInput); - if (Chain.hForward) cmsDeleteTransform(Chain.hForward); - if (Chain.hReverse) cmsDeleteTransform(Chain.hReverse); - if (hLab) cmsCloseProfile(hLab); - - // And return computed hull - return Gamut; -} - -// Total Area Coverage estimation ---------------------------------------------------------------- - -typedef struct { - cmsUInt32Number nOutputChans; - cmsHTRANSFORM hRoundTrip; - cmsFloat32Number MaxTAC; - cmsFloat32Number MaxInput[cmsMAXCHANNELS]; - -} cmsTACestimator; - - -// This callback just accounts the maximum ink dropped in the given node. It does not populate any -// memory, as the destination table is NULL. Its only purpose it to know the global maximum. -static -int EstimateTAC(register const cmsUInt16Number In[], register cmsUInt16Number Out[], register void * Cargo) -{ - cmsTACestimator* bp = (cmsTACestimator*) Cargo; - cmsFloat32Number RoundTrip[cmsMAXCHANNELS]; - cmsUInt32Number i; - cmsFloat32Number Sum; - - - // Evaluate the xform - cmsDoTransform(bp->hRoundTrip, In, RoundTrip, 1); - - // All all amounts of ink - for (Sum=0, i=0; i < bp ->nOutputChans; i++) - Sum += RoundTrip[i]; - - // If above maximum, keep track of input values - if (Sum > bp ->MaxTAC) { - - bp ->MaxTAC = Sum; - - for (i=0; i < bp ->nOutputChans; i++) { - bp ->MaxInput[i] = In[i]; - } - } - - return TRUE; - - cmsUNUSED_PARAMETER(Out); -} - - -// Detect Total area coverage of the profile -cmsFloat64Number CMSEXPORT cmsDetectTAC(cmsHPROFILE hProfile) -{ - cmsTACestimator bp; - cmsUInt32Number dwFormatter; - cmsUInt32Number GridPoints[MAX_INPUT_DIMENSIONS]; - cmsHPROFILE hLab; - cmsContext ContextID = cmsGetProfileContextID(hProfile); - - // TAC only works on output profiles - if (cmsGetDeviceClass(hProfile) != cmsSigOutputClass) { - return 0; - } - - // Create a fake formatter for result - dwFormatter = cmsFormatterForColorspaceOfProfile(hProfile, 4, TRUE); - - bp.nOutputChans = T_CHANNELS(dwFormatter); - bp.MaxTAC = 0; // Initial TAC is 0 - - // for safety - if (bp.nOutputChans >= cmsMAXCHANNELS) return 0; - - hLab = cmsCreateLab4ProfileTHR(ContextID, NULL); - if (hLab == NULL) return 0; - // Setup a roundtrip on perceptual intent in output profile for TAC estimation - bp.hRoundTrip = cmsCreateTransformTHR(ContextID, hLab, TYPE_Lab_16, - hProfile, dwFormatter, INTENT_PERCEPTUAL, cmsFLAGS_NOOPTIMIZE|cmsFLAGS_NOCACHE); - - cmsCloseProfile(hLab); - if (bp.hRoundTrip == NULL) return 0; - - // For L* we only need black and white. For C* we need many points - GridPoints[0] = 6; - GridPoints[1] = 74; - GridPoints[2] = 74; - - - if (!cmsSliceSpace16(3, GridPoints, EstimateTAC, &bp)) { - bp.MaxTAC = 0; - } - - cmsDeleteTransform(bp.hRoundTrip); - - // Results in % - return bp.MaxTAC; -} - - -// Carefully, clamp on CIELab space. - -cmsBool CMSEXPORT cmsDesaturateLab(cmsCIELab* Lab, - double amax, double amin, - double bmax, double bmin) -{ - - // Whole Luma surface to zero - - if (Lab -> L < 0) { - - Lab-> L = Lab->a = Lab-> b = 0.0; - return FALSE; - } - - // Clamp white, DISCARD HIGHLIGHTS. This is done - // in such way because icc spec doesn't allow the - // use of L>100 as a highlight means. - - if (Lab->L > 100) - Lab -> L = 100; - - // Check out gamut prism, on a, b faces - - if (Lab -> a < amin || Lab->a > amax|| - Lab -> b < bmin || Lab->b > bmax) { - - cmsCIELCh LCh; - double h, slope; - - // Falls outside a, b limits. Transports to LCh space, - // and then do the clipping - - - if (Lab -> a == 0.0) { // Is hue exactly 90? - - // atan will not work, so clamp here - Lab -> b = Lab->b < 0 ? bmin : bmax; - return TRUE; - } - - cmsLab2LCh(&LCh, Lab); - - slope = Lab -> b / Lab -> a; - h = LCh.h; - - // There are 4 zones - - if ((h >= 0. && h < 45.) || - (h >= 315 && h <= 360.)) { - - // clip by amax - Lab -> a = amax; - Lab -> b = amax * slope; - } - else - if (h >= 45. && h < 135.) - { - // clip by bmax - Lab -> b = bmax; - Lab -> a = bmax / slope; - } - else - if (h >= 135. && h < 225.) { - // clip by amin - Lab -> a = amin; - Lab -> b = amin * slope; - - } - else - if (h >= 225. && h < 315.) { - // clip by bmin - Lab -> b = bmin; - Lab -> a = bmin / slope; - } - else { - cmsSignalError(0, cmsERROR_RANGE, "Invalid angle"); - return FALSE; - } - - } - - return TRUE; -} +//--------------------------------------------------------------------------------- +// +// Little Color Management System +// Copyright (c) 1998-2012 Marti Maria Saguer +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the "Software"), +// to deal in the Software without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Software, and to permit persons to whom the Software +// is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO +// THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +//--------------------------------------------------------------------------------- +// + +#include "lcms2_internal.h" + + +// Auxiliar: append a Lab identity after the given sequence of profiles +// and return the transform. Lab profile is closed, rest of profiles are kept open. +cmsHTRANSFORM _cmsChain2Lab(cmsContext ContextID, + cmsUInt32Number nProfiles, + cmsUInt32Number InputFormat, + cmsUInt32Number OutputFormat, + const cmsUInt32Number Intents[], + const cmsHPROFILE hProfiles[], + const cmsBool BPC[], + const cmsFloat64Number AdaptationStates[], + cmsUInt32Number dwFlags) +{ + cmsHTRANSFORM xform; + cmsHPROFILE hLab; + cmsHPROFILE ProfileList[256]; + cmsBool BPCList[256]; + cmsFloat64Number AdaptationList[256]; + cmsUInt32Number IntentList[256]; + cmsUInt32Number i; + + // This is a rather big number and there is no need of dynamic memory + // since we are adding a profile, 254 + 1 = 255 and this is the limit + if (nProfiles > 254) return NULL; + + // The output space + hLab = cmsCreateLab4ProfileTHR(ContextID, NULL); + if (hLab == NULL) return NULL; + + // Create a copy of parameters + for (i=0; i < nProfiles; i++) { + + ProfileList[i] = hProfiles[i]; + BPCList[i] = BPC[i]; + AdaptationList[i] = AdaptationStates[i]; + IntentList[i] = Intents[i]; + } + + // Place Lab identity at chain's end. + ProfileList[nProfiles] = hLab; + BPCList[nProfiles] = 0; + AdaptationList[nProfiles] = 1.0; + IntentList[nProfiles] = INTENT_RELATIVE_COLORIMETRIC; + + // Create the transform + xform = cmsCreateExtendedTransform(ContextID, nProfiles + 1, ProfileList, + BPCList, + IntentList, + AdaptationList, + NULL, 0, + InputFormat, + OutputFormat, + dwFlags); + + cmsCloseProfile(hLab); + + return xform; +} + + +// Compute K -> L* relationship. Flags may include black point compensation. In this case, +// the relationship is assumed from the profile with BPC to a black point zero. +static +cmsToneCurve* ComputeKToLstar(cmsContext ContextID, + cmsUInt32Number nPoints, + cmsUInt32Number nProfiles, + const cmsUInt32Number Intents[], + const cmsHPROFILE hProfiles[], + const cmsBool BPC[], + const cmsFloat64Number AdaptationStates[], + cmsUInt32Number dwFlags) +{ + cmsToneCurve* out = NULL; + cmsUInt32Number i; + cmsHTRANSFORM xform; + cmsCIELab Lab; + cmsFloat32Number cmyk[4]; + cmsFloat32Number* SampledPoints; + + xform = _cmsChain2Lab(ContextID, nProfiles, TYPE_CMYK_FLT, TYPE_Lab_DBL, Intents, hProfiles, BPC, AdaptationStates, dwFlags); + if (xform == NULL) return NULL; + + SampledPoints = (cmsFloat32Number*) _cmsCalloc(ContextID, nPoints, sizeof(cmsFloat32Number)); + if (SampledPoints == NULL) goto Error; + + for (i=0; i < nPoints; i++) { + + cmyk[0] = 0; + cmyk[1] = 0; + cmyk[2] = 0; + cmyk[3] = (cmsFloat32Number) ((i * 100.0) / (nPoints-1)); + + cmsDoTransform(xform, cmyk, &Lab, 1); + SampledPoints[i]= (cmsFloat32Number) (1.0 - Lab.L / 100.0); // Negate K for easier operation + } + + out = cmsBuildTabulatedToneCurveFloat(ContextID, nPoints, SampledPoints); + +Error: + + cmsDeleteTransform(xform); + if (SampledPoints) _cmsFree(ContextID, SampledPoints); + + return out; +} + + +// Compute Black tone curve on a CMYK -> CMYK transform. This is done by +// using the proof direction on both profiles to find K->L* relationship +// then joining both curves. dwFlags may include black point compensation. +cmsToneCurve* _cmsBuildKToneCurve(cmsContext ContextID, + cmsUInt32Number nPoints, + cmsUInt32Number nProfiles, + const cmsUInt32Number Intents[], + const cmsHPROFILE hProfiles[], + const cmsBool BPC[], + const cmsFloat64Number AdaptationStates[], + cmsUInt32Number dwFlags) +{ + cmsToneCurve *in, *out, *KTone; + + // Make sure CMYK -> CMYK + if (cmsGetColorSpace(hProfiles[0]) != cmsSigCmykData || + cmsGetColorSpace(hProfiles[nProfiles-1])!= cmsSigCmykData) return NULL; + + + // Make sure last is an output profile + if (cmsGetDeviceClass(hProfiles[nProfiles - 1]) != cmsSigOutputClass) return NULL; + + // Create individual curves. BPC works also as each K to L* is + // computed as a BPC to zero black point in case of L* + in = ComputeKToLstar(ContextID, nPoints, nProfiles - 1, Intents, hProfiles, BPC, AdaptationStates, dwFlags); + if (in == NULL) return NULL; + + out = ComputeKToLstar(ContextID, nPoints, 1, + Intents + (nProfiles - 1), + &hProfiles [nProfiles - 1], + BPC + (nProfiles - 1), + AdaptationStates + (nProfiles - 1), + dwFlags); + if (out == NULL) { + cmsFreeToneCurve(in); + return NULL; + } + + // Build the relationship. This effectively limits the maximum accuracy to 16 bits, but + // since this is used on black-preserving LUTs, we are not loosing accuracy in any case + KTone = cmsJoinToneCurve(ContextID, in, out, nPoints); + + // Get rid of components + cmsFreeToneCurve(in); cmsFreeToneCurve(out); + + // Something went wrong... + if (KTone == NULL) return NULL; + + // Make sure it is monotonic + if (!cmsIsToneCurveMonotonic(KTone)) { + cmsFreeToneCurve(KTone); + return NULL; + } + + return KTone; +} + + +// Gamut LUT Creation ----------------------------------------------------------------------------------------- + +// Used by gamut & softproofing + +typedef struct { + + cmsHTRANSFORM hInput; // From whatever input color space. 16 bits to DBL + cmsHTRANSFORM hForward, hReverse; // Transforms going from Lab to colorant and back + cmsFloat64Number Thereshold; // The thereshold after which is considered out of gamut + + } GAMUTCHAIN; + +// This sampler does compute gamut boundaries by comparing original +// values with a transform going back and forth. Values above ERR_THERESHOLD +// of maximum are considered out of gamut. + +#define ERR_THERESHOLD 5 + + +static +int GamutSampler(register const cmsUInt16Number In[], register cmsUInt16Number Out[], register void* Cargo) +{ + GAMUTCHAIN* t = (GAMUTCHAIN* ) Cargo; + cmsCIELab LabIn1, LabOut1; + cmsCIELab LabIn2, LabOut2; + cmsUInt16Number Proof[cmsMAXCHANNELS], Proof2[cmsMAXCHANNELS]; + cmsFloat64Number dE1, dE2, ErrorRatio; + + // Assume in-gamut by default. + ErrorRatio = 1.0; + + // Convert input to Lab + cmsDoTransform(t -> hInput, In, &LabIn1, 1); + + // converts from PCS to colorant. This always + // does return in-gamut values, + cmsDoTransform(t -> hForward, &LabIn1, Proof, 1); + + // Now, do the inverse, from colorant to PCS. + cmsDoTransform(t -> hReverse, Proof, &LabOut1, 1); + + memmove(&LabIn2, &LabOut1, sizeof(cmsCIELab)); + + // Try again, but this time taking Check as input + cmsDoTransform(t -> hForward, &LabOut1, Proof2, 1); + cmsDoTransform(t -> hReverse, Proof2, &LabOut2, 1); + + // Take difference of direct value + dE1 = cmsDeltaE(&LabIn1, &LabOut1); + + // Take difference of converted value + dE2 = cmsDeltaE(&LabIn2, &LabOut2); + + + // if dE1 is small and dE2 is small, value is likely to be in gamut + if (dE1 < t->Thereshold && dE2 < t->Thereshold) + Out[0] = 0; + else { + + // if dE1 is small and dE2 is big, undefined. Assume in gamut + if (dE1 < t->Thereshold && dE2 > t->Thereshold) + Out[0] = 0; + else + // dE1 is big and dE2 is small, clearly out of gamut + if (dE1 > t->Thereshold && dE2 < t->Thereshold) + Out[0] = (cmsUInt16Number) _cmsQuickFloor((dE1 - t->Thereshold) + .5); + else { + + // dE1 is big and dE2 is also big, could be due to perceptual mapping + // so take error ratio + if (dE2 == 0.0) + ErrorRatio = dE1; + else + ErrorRatio = dE1 / dE2; + + if (ErrorRatio > t->Thereshold) + Out[0] = (cmsUInt16Number) _cmsQuickFloor((ErrorRatio - t->Thereshold) + .5); + else + Out[0] = 0; + } + } + + + return TRUE; +} + +// Does compute a gamut LUT going back and forth across pcs -> relativ. colorimetric intent -> pcs +// the dE obtained is then annotated on the LUT. Values truely out of gamut are clipped to dE = 0xFFFE +// and values changed are supposed to be handled by any gamut remapping, so, are out of gamut as well. +// +// **WARNING: This algorithm does assume that gamut remapping algorithms does NOT move in-gamut colors, +// of course, many perceptual and saturation intents does not work in such way, but relativ. ones should. + +cmsPipeline* _cmsCreateGamutCheckPipeline(cmsContext ContextID, + cmsHPROFILE hProfiles[], + cmsBool BPC[], + cmsUInt32Number Intents[], + cmsFloat64Number AdaptationStates[], + cmsUInt32Number nGamutPCSposition, + cmsHPROFILE hGamut) +{ + cmsHPROFILE hLab; + cmsPipeline* Gamut; + cmsStage* CLUT; + cmsUInt32Number dwFormat; + GAMUTCHAIN Chain; + int nChannels, nGridpoints; + cmsColorSpaceSignature ColorSpace; + cmsUInt32Number i; + cmsHPROFILE ProfileList[256]; + cmsBool BPCList[256]; + cmsFloat64Number AdaptationList[256]; + cmsUInt32Number IntentList[256]; + + memset(&Chain, 0, sizeof(GAMUTCHAIN)); + + + if (nGamutPCSposition <= 0 || nGamutPCSposition > 255) { + cmsSignalError(ContextID, cmsERROR_RANGE, "Wrong position of PCS. 1..255 expected, %d found.", nGamutPCSposition); + return NULL; + } + + hLab = cmsCreateLab4ProfileTHR(ContextID, NULL); + if (hLab == NULL) return NULL; + + + // The figure of merit. On matrix-shaper profiles, should be almost zero as + // the conversion is pretty exact. On LUT based profiles, different resolutions + // of input and output CLUT may result in differences. + + if (cmsIsMatrixShaper(hGamut)) { + + Chain.Thereshold = 1.0; + } + else { + Chain.Thereshold = ERR_THERESHOLD; + } + + + // Create a copy of parameters + for (i=0; i < nGamutPCSposition; i++) { + ProfileList[i] = hProfiles[i]; + BPCList[i] = BPC[i]; + AdaptationList[i] = AdaptationStates[i]; + IntentList[i] = Intents[i]; + } + + // Fill Lab identity + ProfileList[nGamutPCSposition] = hLab; + BPCList[nGamutPCSposition] = 0; + AdaptationList[nGamutPCSposition] = 1.0; + IntentList[nGamutPCSposition] = INTENT_RELATIVE_COLORIMETRIC; + + + ColorSpace = cmsGetColorSpace(hGamut); + + nChannels = cmsChannelsOf(ColorSpace); + nGridpoints = _cmsReasonableGridpointsByColorspace(ColorSpace, cmsFLAGS_HIGHRESPRECALC); + dwFormat = (CHANNELS_SH(nChannels)|BYTES_SH(2)); + + // 16 bits to Lab double + Chain.hInput = cmsCreateExtendedTransform(ContextID, + nGamutPCSposition + 1, + ProfileList, + BPCList, + IntentList, + AdaptationList, + NULL, 0, + dwFormat, TYPE_Lab_DBL, + cmsFLAGS_NOCACHE); + + + // Does create the forward step. Lab double to device + dwFormat = (CHANNELS_SH(nChannels)|BYTES_SH(2)); + Chain.hForward = cmsCreateTransformTHR(ContextID, + hLab, TYPE_Lab_DBL, + hGamut, dwFormat, + INTENT_RELATIVE_COLORIMETRIC, + cmsFLAGS_NOCACHE); + + // Does create the backwards step + Chain.hReverse = cmsCreateTransformTHR(ContextID, hGamut, dwFormat, + hLab, TYPE_Lab_DBL, + INTENT_RELATIVE_COLORIMETRIC, + cmsFLAGS_NOCACHE); + + + // All ok? + if (Chain.hInput && Chain.hForward && Chain.hReverse) { + + // Go on, try to compute gamut LUT from PCS. This consist on a single channel containing + // dE when doing a transform back and forth on the colorimetric intent. + + Gamut = cmsPipelineAlloc(ContextID, 3, 1); + if (Gamut != NULL) { + + CLUT = cmsStageAllocCLut16bit(ContextID, nGridpoints, nChannels, 1, NULL); + if (!cmsPipelineInsertStage(Gamut, cmsAT_BEGIN, CLUT)) { + cmsPipelineFree(Gamut); + Gamut = NULL; + } + else { + cmsStageSampleCLut16bit(CLUT, GamutSampler, (void*) &Chain, 0); + } + } + } + else + Gamut = NULL; // Didn't work... + + // Free all needed stuff. + if (Chain.hInput) cmsDeleteTransform(Chain.hInput); + if (Chain.hForward) cmsDeleteTransform(Chain.hForward); + if (Chain.hReverse) cmsDeleteTransform(Chain.hReverse); + if (hLab) cmsCloseProfile(hLab); + + // And return computed hull + return Gamut; +} + +// Total Area Coverage estimation ---------------------------------------------------------------- + +typedef struct { + cmsUInt32Number nOutputChans; + cmsHTRANSFORM hRoundTrip; + cmsFloat32Number MaxTAC; + cmsFloat32Number MaxInput[cmsMAXCHANNELS]; + +} cmsTACestimator; + + +// This callback just accounts the maximum ink dropped in the given node. It does not populate any +// memory, as the destination table is NULL. Its only purpose it to know the global maximum. +static +int EstimateTAC(register const cmsUInt16Number In[], register cmsUInt16Number Out[], register void * Cargo) +{ + cmsTACestimator* bp = (cmsTACestimator*) Cargo; + cmsFloat32Number RoundTrip[cmsMAXCHANNELS]; + cmsUInt32Number i; + cmsFloat32Number Sum; + + + // Evaluate the xform + cmsDoTransform(bp->hRoundTrip, In, RoundTrip, 1); + + // All all amounts of ink + for (Sum=0, i=0; i < bp ->nOutputChans; i++) + Sum += RoundTrip[i]; + + // If above maximum, keep track of input values + if (Sum > bp ->MaxTAC) { + + bp ->MaxTAC = Sum; + + for (i=0; i < bp ->nOutputChans; i++) { + bp ->MaxInput[i] = In[i]; + } + } + + return TRUE; + + cmsUNUSED_PARAMETER(Out); +} + + +// Detect Total area coverage of the profile +cmsFloat64Number CMSEXPORT cmsDetectTAC(cmsHPROFILE hProfile) +{ + cmsTACestimator bp; + cmsUInt32Number dwFormatter; + cmsUInt32Number GridPoints[MAX_INPUT_DIMENSIONS]; + cmsHPROFILE hLab; + cmsContext ContextID = cmsGetProfileContextID(hProfile); + + // TAC only works on output profiles + if (cmsGetDeviceClass(hProfile) != cmsSigOutputClass) { + return 0; + } + + // Create a fake formatter for result + dwFormatter = cmsFormatterForColorspaceOfProfile(hProfile, 4, TRUE); + + bp.nOutputChans = T_CHANNELS(dwFormatter); + bp.MaxTAC = 0; // Initial TAC is 0 + + // for safety + if (bp.nOutputChans >= cmsMAXCHANNELS) return 0; + + hLab = cmsCreateLab4ProfileTHR(ContextID, NULL); + if (hLab == NULL) return 0; + // Setup a roundtrip on perceptual intent in output profile for TAC estimation + bp.hRoundTrip = cmsCreateTransformTHR(ContextID, hLab, TYPE_Lab_16, + hProfile, dwFormatter, INTENT_PERCEPTUAL, cmsFLAGS_NOOPTIMIZE|cmsFLAGS_NOCACHE); + + cmsCloseProfile(hLab); + if (bp.hRoundTrip == NULL) return 0; + + // For L* we only need black and white. For C* we need many points + GridPoints[0] = 6; + GridPoints[1] = 74; + GridPoints[2] = 74; + + + if (!cmsSliceSpace16(3, GridPoints, EstimateTAC, &bp)) { + bp.MaxTAC = 0; + } + + cmsDeleteTransform(bp.hRoundTrip); + + // Results in % + return bp.MaxTAC; +} + + +// Carefully, clamp on CIELab space. + +cmsBool CMSEXPORT cmsDesaturateLab(cmsCIELab* Lab, + double amax, double amin, + double bmax, double bmin) +{ + + // Whole Luma surface to zero + + if (Lab -> L < 0) { + + Lab-> L = Lab->a = Lab-> b = 0.0; + return FALSE; + } + + // Clamp white, DISCARD HIGHLIGHTS. This is done + // in such way because icc spec doesn't allow the + // use of L>100 as a highlight means. + + if (Lab->L > 100) + Lab -> L = 100; + + // Check out gamut prism, on a, b faces + + if (Lab -> a < amin || Lab->a > amax|| + Lab -> b < bmin || Lab->b > bmax) { + + cmsCIELCh LCh; + double h, slope; + + // Falls outside a, b limits. Transports to LCh space, + // and then do the clipping + + + if (Lab -> a == 0.0) { // Is hue exactly 90? + + // atan will not work, so clamp here + Lab -> b = Lab->b < 0 ? bmin : bmax; + return TRUE; + } + + cmsLab2LCh(&LCh, Lab); + + slope = Lab -> b / Lab -> a; + h = LCh.h; + + // There are 4 zones + + if ((h >= 0. && h < 45.) || + (h >= 315 && h <= 360.)) { + + // clip by amax + Lab -> a = amax; + Lab -> b = amax * slope; + } + else + if (h >= 45. && h < 135.) + { + // clip by bmax + Lab -> b = bmax; + Lab -> a = bmax / slope; + } + else + if (h >= 135. && h < 225.) { + // clip by amin + Lab -> a = amin; + Lab -> b = amin * slope; + + } + else + if (h >= 225. && h < 315.) { + // clip by bmin + Lab -> b = bmin; + Lab -> a = bmin / slope; + } + else { + cmsSignalError(0, cmsERROR_RANGE, "Invalid angle"); + return FALSE; + } + + } + + return TRUE; +} diff -Nru lcms2-2.5/src/cmsintrp.c lcms2-2.6/src/cmsintrp.c --- lcms2-2.5/src/cmsintrp.c 2013-06-27 16:01:28.000000000 +0000 +++ lcms2-2.6/src/cmsintrp.c 2014-03-17 16:09:30.000000000 +0000 @@ -33,32 +33,58 @@ static cmsInterpFunction DefaultInterpolatorsFactory(cmsUInt32Number nInputChannels, cmsUInt32Number nOutputChannels, cmsUInt32Number dwFlags); // This is the default factory -static cmsInterpFnFactory Interpolators = DefaultInterpolatorsFactory; +_cmsInterpPluginChunkType _cmsInterpPluginChunk = { NULL }; + +// The interpolation plug-in memory chunk allocator/dup +void _cmsAllocInterpPluginChunk(struct _cmsContext_struct* ctx, const struct _cmsContext_struct* src) +{ + void* from; + + _cmsAssert(ctx != NULL); + + if (src != NULL) { + from = src ->chunks[InterpPlugin]; + } + else { + static _cmsInterpPluginChunkType InterpPluginChunk = { NULL }; + + from = &InterpPluginChunk; + } + + _cmsAssert(from != NULL); + ctx ->chunks[InterpPlugin] = _cmsSubAllocDup(ctx ->MemPool, from, sizeof(_cmsInterpPluginChunkType)); +} // Main plug-in entry -cmsBool _cmsRegisterInterpPlugin(cmsPluginBase* Data) +cmsBool _cmsRegisterInterpPlugin(cmsContext ContextID, cmsPluginBase* Data) { cmsPluginInterpolation* Plugin = (cmsPluginInterpolation*) Data; + _cmsInterpPluginChunkType* ptr = (_cmsInterpPluginChunkType*) _cmsContextGetClientChunk(ContextID, InterpPlugin); if (Data == NULL) { - Interpolators = DefaultInterpolatorsFactory; + ptr ->Interpolators = NULL; return TRUE; } // Set replacement functions - Interpolators = Plugin ->InterpolatorsFactory; + ptr ->Interpolators = Plugin ->InterpolatorsFactory; return TRUE; } // Set the interpolation method -cmsBool _cmsSetInterpolationRoutine(cmsInterpParams* p) -{ - // Invoke factory, possibly in the Plug-in - p ->Interpolation = Interpolators(p -> nInputs, p ->nOutputs, p ->dwFlags); - +cmsBool _cmsSetInterpolationRoutine(cmsContext ContextID, cmsInterpParams* p) +{ + _cmsInterpPluginChunkType* ptr = (_cmsInterpPluginChunkType*) _cmsContextGetClientChunk(ContextID, InterpPlugin); + + p ->Interpolation.Lerp16 = NULL; + + // Invoke factory, possibly in the Plug-in + if (ptr ->Interpolators != NULL) + p ->Interpolation = ptr->Interpolators(p -> nInputs, p ->nOutputs, p ->dwFlags); + // If unsupported by the plug-in, go for the LittleCMS default. // If happens only if an extern plug-in is being used if (p ->Interpolation.Lerp16 == NULL) @@ -68,6 +94,7 @@ if (p ->Interpolation.Lerp16 == NULL) { return FALSE; } + return TRUE; } @@ -112,7 +139,7 @@ p ->opta[i] = p ->opta[i-1] * nSamples[InputChan-i]; - if (!_cmsSetInterpolationRoutine(p)) { + if (!_cmsSetInterpolationRoutine(ContextID, p)) { cmsSignalError(ContextID, cmsERROR_UNKNOWN_EXTENSION, "Unsupported interpolation (%d->%d channels)", InputChan, OutputChan); _cmsFree(ContextID, p); return NULL; @@ -185,6 +212,11 @@ Output[0] = LinearInterp(rest, y0, y1); } +// To prevent out of bounds indexing +cmsINLINE cmsFloat32Number fclamp(cmsFloat32Number v) +{ + return v < 0.0f ? 0.0f : (v > 1.0f ? 1.0f : v); +} // Floating-point version of 1D interpolation static @@ -197,13 +229,15 @@ int cell0, cell1; const cmsFloat32Number* LutTable = (cmsFloat32Number*) p ->Table; + val2 = fclamp(Value[0]); + // if last value... - if (Value[0] == 1.0) { + if (val2 == 1.0) { Output[0] = LutTable[p -> Domain[0]]; return; } - val2 = p -> Domain[0] * Value[0]; + val2 *= p -> Domain[0]; cell0 = (int) floor(val2); cell1 = (int) ceil(val2); @@ -262,13 +296,15 @@ cmsUInt32Number OutChan; const cmsFloat32Number* LutTable = (cmsFloat32Number*) p ->Table; + val2 = fclamp(Value[0]); + // if last value... - if (Value[0] == 1.0) { + if (val2 == 1.0) { Output[0] = LutTable[p -> Domain[0]]; return; } - val2 = p -> Domain[0] * Value[0]; + val2 *= p -> Domain[0]; cell0 = (int) floor(val2); cell1 = (int) ceil(val2); @@ -309,8 +345,8 @@ dxy; TotalOut = p -> nOutputs; - px = Input[0] * p->Domain[0]; - py = Input[1] * p->Domain[1]; + px = fclamp(Input[0]) * p->Domain[0]; + py = fclamp(Input[1]) * p->Domain[1]; x0 = (int) _cmsQuickFloor(px); fx = px - (cmsFloat32Number) x0; y0 = (int) _cmsQuickFloor(py); fy = py - (cmsFloat32Number) y0; @@ -424,20 +460,9 @@ TotalOut = p -> nOutputs; // We need some clipping here - px = Input[0]; - py = Input[1]; - pz = Input[2]; - - if (px < 0) px = 0; - if (px > 1) px = 1; - if (py < 0) py = 0; - if (py > 1) py = 1; - if (pz < 0) pz = 0; - if (pz > 1) pz = 1; - - px *= p->Domain[0]; - py *= p->Domain[1]; - pz *= p->Domain[2]; + px = fclamp(Input[0]) * p->Domain[0]; + py = fclamp(Input[1]) * p->Domain[1]; + pz = fclamp(Input[2]) * p->Domain[2]; x0 = (int) _cmsQuickFloor(px); fx = px - (cmsFloat32Number) x0; y0 = (int) _cmsQuickFloor(py); fy = py - (cmsFloat32Number) y0; @@ -579,20 +604,9 @@ TotalOut = p -> nOutputs; // We need some clipping here - px = Input[0]; - py = Input[1]; - pz = Input[2]; - - if (px < 0) px = 0; - if (px > 1) px = 1; - if (py < 0) py = 0; - if (py > 1) py = 1; - if (pz < 0) pz = 0; - if (pz > 1) pz = 1; - - px *= p->Domain[0]; - py *= p->Domain[1]; - pz *= p->Domain[2]; + px = fclamp(Input[0]) * p->Domain[0]; + py = fclamp(Input[1]) * p->Domain[1]; + pz = fclamp(Input[2]) * p->Domain[2]; x0 = (int) _cmsQuickFloor(px); rx = (px - (cmsFloat32Number) x0); y0 = (int) _cmsQuickFloor(py); ry = (py - (cmsFloat32Number) y0); @@ -1009,8 +1023,7 @@ cmsFloat32Number Tmp1[MAX_STAGE_CHANNELS], Tmp2[MAX_STAGE_CHANNELS]; cmsInterpParams p1; - - pk = Input[0] * p->Domain[0]; + pk = fclamp(Input[0]) * p->Domain[0]; k0 = _cmsQuickFloor(pk); rest = pk - (cmsFloat32Number) k0; @@ -1097,7 +1110,7 @@ cmsFloat32Number Tmp1[MAX_STAGE_CHANNELS], Tmp2[MAX_STAGE_CHANNELS]; cmsInterpParams p1; - pk = Input[0] * p->Domain[0]; + pk = fclamp(Input[0]) * p->Domain[0]; k0 = _cmsQuickFloor(pk); rest = pk - (cmsFloat32Number) k0; @@ -1184,7 +1197,7 @@ cmsFloat32Number Tmp1[MAX_STAGE_CHANNELS], Tmp2[MAX_STAGE_CHANNELS]; cmsInterpParams p1; - pk = Input[0] * p->Domain[0]; + pk = fclamp(Input[0]) * p->Domain[0]; k0 = _cmsQuickFloor(pk); rest = pk - (cmsFloat32Number) k0; @@ -1269,7 +1282,7 @@ cmsFloat32Number Tmp1[MAX_STAGE_CHANNELS], Tmp2[MAX_STAGE_CHANNELS]; cmsInterpParams p1; - pk = Input[0] * p->Domain[0]; + pk = fclamp(Input[0]) * p->Domain[0]; k0 = _cmsQuickFloor(pk); rest = pk - (cmsFloat32Number) k0; @@ -1354,7 +1367,7 @@ cmsFloat32Number Tmp1[MAX_STAGE_CHANNELS], Tmp2[MAX_STAGE_CHANNELS]; cmsInterpParams p1; - pk = Input[0] * p->Domain[0]; + pk = fclamp(Input[0]) * p->Domain[0]; k0 = _cmsQuickFloor(pk); rest = pk - (cmsFloat32Number) k0; diff -Nru lcms2-2.5/src/cmsio0.c lcms2-2.6/src/cmsio0.c --- lcms2-2.5/src/cmsio0.c 2013-06-27 16:01:28.000000000 +0000 +++ lcms2-2.6/src/cmsio0.c 2014-03-17 16:09:30.000000000 +0000 @@ -200,15 +200,14 @@ if (ResData == NULL) return FALSE; // Housekeeping // Check for available space. Clip. - if (iohandler ->UsedSpace + size > ResData->Size) { - size = ResData ->Size - iohandler ->UsedSpace; + if (ResData->Pointer + size > ResData->Size) { + size = ResData ->Size - ResData->Pointer; } if (size == 0) return TRUE; // Write zero bytes is ok, but does nothing memmove(ResData ->Block + ResData ->Pointer, Ptr, size); ResData ->Pointer += size; - iohandler->UsedSpace += size; if (ResData ->Pointer > iohandler->UsedSpace) iohandler->UsedSpace = ResData ->Pointer; @@ -342,7 +341,7 @@ static cmsUInt32Number FileTell(cmsIOHANDLER* iohandler) { - return ftell((FILE*)iohandler ->stream); + return (cmsUInt32Number) ftell((FILE*)iohandler ->stream); } // Writes data to stream, also keeps used space for further reference. Returns TRUE on success, FALSE on error @@ -385,7 +384,7 @@ cmsSignalError(ContextID, cmsERROR_FILE, "File '%s' not found", FileName); return NULL; } - iohandler -> ReportedSize = cmsfilelength(fm); + iohandler -> ReportedSize = (cmsUInt32Number) cmsfilelength(fm); break; case 'w': @@ -432,7 +431,7 @@ iohandler -> ContextID = ContextID; iohandler -> stream = (void*) Stream; iohandler -> UsedSpace = 0; - iohandler -> ReportedSize = cmsfilelength(Stream); + iohandler -> ReportedSize = (cmsUInt32Number) cmsfilelength(Stream); iohandler -> PhysicalFile[0] = 0; iohandler ->Read = FileRead; @@ -472,6 +471,9 @@ // Set creation date/time memmove(&Icc ->Created, gmtime(&now), sizeof(Icc ->Created)); + // Create a mutex if the user provided proper plugin. NULL otherwise + Icc ->UsrMutex = _cmsCreateMutex(ContextID); + // Return the handle return (cmsHPROFILE) Icc; } @@ -550,9 +552,39 @@ return n; } +// Deletes a tag entry + +static +void _cmsDeleteTagByPos(_cmsICCPROFILE* Icc, int i) +{ + _cmsAssert(Icc != NULL); + _cmsAssert(i >= 0); + + + if (Icc -> TagPtrs[i] != NULL) { + + // Free previous version + if (Icc ->TagSaveAsRaw[i]) { + _cmsFree(Icc ->ContextID, Icc ->TagPtrs[i]); + } + else { + cmsTagTypeHandler* TypeHandler = Icc ->TagTypeHandlers[i]; + + if (TypeHandler != NULL) { + + cmsTagTypeHandler LocalTypeHandler = *TypeHandler; + LocalTypeHandler.ContextID = Icc ->ContextID; // As an additional parameter + LocalTypeHandler.ICCVersion = Icc ->Version; + LocalTypeHandler.FreePtr(&LocalTypeHandler, Icc -> TagPtrs[i]); + Icc ->TagPtrs[i] = NULL; + } + } + + } +} -// Create a new tag entry +// Creates a new tag entry static cmsBool _cmsNewTag(_cmsICCPROFILE* Icc, cmsTagSignature sig, int* NewPos) { @@ -560,15 +592,15 @@ // Search for the tag i = _cmsSearchTag(Icc, sig, FALSE); - - // Now let's do it easy. If the tag has been already written, that's an error if (i >= 0) { - cmsSignalError(Icc ->ContextID, cmsERROR_ALREADY_DEFINED, "Tag '%x' already exists", sig); - return FALSE; + + // Already exists? delete it + _cmsDeleteTagByPos(Icc, i); + *NewPos = i; } else { - // New one + // No, make a new one if (Icc -> TagCount >= MAX_TABLE_TAG) { cmsSignalError(Icc ->ContextID, cmsERROR_RANGE, "Too many tags (%d)", MAX_TABLE_TAG); @@ -925,7 +957,7 @@ // 4.2 -> 0x4200000 - Icc -> Version = BaseToBase((cmsUInt32Number) floor(Version * 100.0), 10, 16) << 16; + Icc -> Version = BaseToBase((cmsUInt32Number) floor(Version * 100.0 + 0.5), 10, 16) << 16; } cmsFloat64Number CMSEXPORT cmsGetProfileVersion(cmsHPROFILE hProfile) @@ -957,6 +989,32 @@ return NULL; } +// Create profile from IOhandler +cmsHPROFILE CMSEXPORT cmsOpenProfileFromIOhandler2THR(cmsContext ContextID, cmsIOHANDLER* io, cmsBool write) +{ + _cmsICCPROFILE* NewIcc; + cmsHPROFILE hEmpty = cmsCreateProfilePlaceholder(ContextID); + + if (hEmpty == NULL) return NULL; + + NewIcc = (_cmsICCPROFILE*) hEmpty; + + NewIcc ->IOhandler = io; + if (write) { + + NewIcc -> IsWrite = TRUE; + return hEmpty; + } + + if (!_cmsReadHeader(NewIcc)) goto Error; + return hEmpty; + +Error: + cmsCloseProfile(hEmpty); + return NULL; +} + + // Create profile from disk file cmsHPROFILE CMSEXPORT cmsOpenProfileFromFileTHR(cmsContext ContextID, const char *lpFileName, const char *sAccess) { @@ -1122,7 +1180,7 @@ else { // Search for support on this tag - TagDescriptor = _cmsGetTagDescriptor(Icc -> TagNames[i]); + TagDescriptor = _cmsGetTagDescriptor(Icc-> ContextID, Icc -> TagNames[i]); if (TagDescriptor == NULL) continue; // Unsupported, ignore it if (TagDescriptor ->DecideType != NULL) { @@ -1134,7 +1192,7 @@ Type = TagDescriptor ->SupportedTypes[0]; } - TypeHandler = _cmsGetTagTypeHandler(Type); + TypeHandler = _cmsGetTagTypeHandler(Icc->ContextID, Type); if (TypeHandler == NULL) { cmsSignalError(Icc ->ContextID, cmsERROR_INTERNAL, "(Internal) no handler for tag %x", Icc -> TagNames[i]); @@ -1202,10 +1260,12 @@ { _cmsICCPROFILE* Icc = (_cmsICCPROFILE*) hProfile; _cmsICCPROFILE Keep; - cmsIOHANDLER* PrevIO; + cmsIOHANDLER* PrevIO = NULL; cmsUInt32Number UsedSpace; cmsContext ContextID; + _cmsAssert(hProfile != NULL); + memmove(&Keep, Icc, sizeof(_cmsICCPROFILE)); ContextID = cmsGetProfileContextID(hProfile); @@ -1214,18 +1274,19 @@ // Pass #1 does compute offsets - if (!_cmsWriteHeader(Icc, 0)) return 0; - if (!SaveTags(Icc, &Keep)) return 0; + if (!_cmsWriteHeader(Icc, 0)) goto Error; + if (!SaveTags(Icc, &Keep)) goto Error; UsedSpace = PrevIO ->UsedSpace; // Pass #2 does save to iohandler if (io != NULL) { + Icc ->IOhandler = io; - if (!SetLinks(Icc)) goto CleanUp; - if (!_cmsWriteHeader(Icc, UsedSpace)) goto CleanUp; - if (!SaveTags(Icc, &Keep)) goto CleanUp; + if (!SetLinks(Icc)) goto Error; + if (!_cmsWriteHeader(Icc, UsedSpace)) goto Error; + if (!SaveTags(Icc, &Keep)) goto Error; } memmove(Icc, &Keep, sizeof(_cmsICCPROFILE)); @@ -1234,7 +1295,7 @@ return UsedSpace; -CleanUp: +Error: cmsCloseIOhandler(PrevIO); memmove(Icc, &Keep, sizeof(_cmsICCPROFILE)); return 0; @@ -1282,11 +1343,13 @@ cmsIOHANDLER* io; cmsContext ContextID = cmsGetProfileContextID(hProfile); + _cmsAssert(BytesNeeded != NULL); + // Should we just calculate the needed space? if (MemPtr == NULL) { *BytesNeeded = cmsSaveProfileToIOhandler(hProfile, NULL); - return TRUE; + return (*BytesNeeded == 0) ? FALSE : TRUE; } // That is a real write operation @@ -1339,6 +1402,8 @@ rc &= cmsCloseIOhandler(Icc->IOhandler); } + _cmsDestroyMutex(Icc->ContextID, Icc->UsrMutex); + _cmsFree(Icc ->ContextID, Icc); // Free placeholder memory return rc; @@ -1379,14 +1444,18 @@ cmsUInt32Number ElemCount; int n; + if (!_cmsLockMutex(Icc->ContextID, Icc ->UsrMutex)) return NULL; + n = _cmsSearchTag(Icc, sig, TRUE); - if (n < 0) return NULL; // Not found, return NULL + if (n < 0) goto Error; // Not found, return NULL // If the element is already in memory, return the pointer if (Icc -> TagPtrs[n]) { - if (Icc ->TagSaveAsRaw[n]) return NULL; // We don't support read raw tags as cooked + if (Icc ->TagSaveAsRaw[n]) goto Error; // We don't support read raw tags as cooked + + _cmsUnlockMutex(Icc->ContextID, Icc ->UsrMutex); return Icc -> TagPtrs[n]; } @@ -1396,23 +1465,32 @@ // Seek to its location if (!io -> Seek(io, Offset)) - return NULL; + goto Error; // Search for support on this tag - TagDescriptor = _cmsGetTagDescriptor(sig); - if (TagDescriptor == NULL) return NULL; // Unsupported. + TagDescriptor = _cmsGetTagDescriptor(Icc-> ContextID, sig); + if (TagDescriptor == NULL) { + + char String[5]; + + _cmsTagSignature2String(String, sig); + + // An unknown element was found. + cmsSignalError(Icc ->ContextID, cmsERROR_UNKNOWN_EXTENSION, "Unknown tag type '%s' found.", String); + goto Error; // Unsupported. + } // if supported, get type and check if in list BaseType = _cmsReadTypeBase(io); - if (BaseType == 0) return NULL; + if (BaseType == 0) goto Error; - if (!IsTypeSupported(TagDescriptor, BaseType)) return NULL; + if (!IsTypeSupported(TagDescriptor, BaseType)) goto Error; TagSize -= 8; // Alredy read by the type base logic // Get type handler - TypeHandler = _cmsGetTagTypeHandler(BaseType); - if (TypeHandler == NULL) return NULL; + TypeHandler = _cmsGetTagTypeHandler(Icc ->ContextID, BaseType); + if (TypeHandler == NULL) goto Error; LocalTypeHandler = *TypeHandler; @@ -1431,7 +1509,7 @@ _cmsTagSignature2String(String, sig); cmsSignalError(Icc ->ContextID, cmsERROR_CORRUPTION_DETECTED, "Corrupted tag '%s'", String); - return NULL; + goto Error; } // This is a weird error that may be a symptom of something more serious, the number of @@ -1447,7 +1525,14 @@ // Return the data + _cmsUnlockMutex(Icc->ContextID, Icc ->UsrMutex); return Icc -> TagPtrs[n]; + + + // Return error and unlock tha data +Error: + _cmsUnlockMutex(Icc->ContextID, Icc ->UsrMutex); + return NULL; } @@ -1481,49 +1566,26 @@ cmsFloat64Number Version; char TypeString[5], SigString[5]; + if (!_cmsLockMutex(Icc->ContextID, Icc ->UsrMutex)) return FALSE; + // To delete tags. if (data == NULL) { + // Delete the tag i = _cmsSearchTag(Icc, sig, FALSE); - if (i >= 0) + if (i >= 0) { + + // Use zero as a mark of deleted + _cmsDeleteTagByPos(Icc, i); Icc ->TagNames[i] = (cmsTagSignature) 0; - // Unsupported by now, reserved for future ampliations (delete) - return FALSE; + _cmsUnlockMutex(Icc->ContextID, Icc ->UsrMutex); + return TRUE; + } + // Didn't find the tag + goto Error; } - i = _cmsSearchTag(Icc, sig, FALSE); - if (i >=0) { - - if (Icc -> TagPtrs[i] != NULL) { - - // Already exists. Free previous version - if (Icc ->TagSaveAsRaw[i]) { - _cmsFree(Icc ->ContextID, Icc ->TagPtrs[i]); - } - else { - TypeHandler = Icc ->TagTypeHandlers[i]; - - if (TypeHandler != NULL) { - - LocalTypeHandler = *TypeHandler; - LocalTypeHandler.ContextID = Icc ->ContextID; // As an additional parameter - LocalTypeHandler.ICCVersion = Icc ->Version; - LocalTypeHandler.FreePtr(&LocalTypeHandler, Icc -> TagPtrs[i]); - } - } - } - } - else { - // New one - i = Icc -> TagCount; - - if (i >= MAX_TABLE_TAG) { - cmsSignalError(Icc ->ContextID, cmsERROR_RANGE, "Too many tags (%d)", MAX_TABLE_TAG); - return FALSE; - } - - Icc -> TagCount++; - } + if (!_cmsNewTag(Icc, sig, &i)) goto Error; // This is not raw Icc ->TagSaveAsRaw[i] = FALSE; @@ -1532,10 +1594,10 @@ Icc ->TagLinked[i] = (cmsTagSignature) 0; // Get information about the TAG. - TagDescriptor = _cmsGetTagDescriptor(sig); + TagDescriptor = _cmsGetTagDescriptor(Icc-> ContextID, sig); if (TagDescriptor == NULL){ cmsSignalError(Icc ->ContextID, cmsERROR_UNKNOWN_EXTENSION, "Unsupported tag '%x'", sig); - return FALSE; + goto Error; } @@ -1553,7 +1615,6 @@ } else { - Type = TagDescriptor ->SupportedTypes[0]; } @@ -1564,18 +1625,18 @@ _cmsTagSignature2String(SigString, sig); cmsSignalError(Icc ->ContextID, cmsERROR_UNKNOWN_EXTENSION, "Unsupported type '%s' for tag '%s'", TypeString, SigString); - return FALSE; + goto Error; } // Does we have a handler for this type? - TypeHandler = _cmsGetTagTypeHandler(Type); + TypeHandler = _cmsGetTagTypeHandler(Icc->ContextID, Type); if (TypeHandler == NULL) { _cmsTagSignature2String(TypeString, (cmsTagSignature) Type); _cmsTagSignature2String(SigString, sig); cmsSignalError(Icc ->ContextID, cmsERROR_UNKNOWN_EXTENSION, "Unsupported type '%s' for tag '%s'", TypeString, SigString); - return FALSE; // Should never happen + goto Error; // Should never happen } @@ -1588,7 +1649,7 @@ LocalTypeHandler = *TypeHandler; LocalTypeHandler.ContextID = Icc ->ContextID; LocalTypeHandler.ICCVersion = Icc ->Version; - Icc ->TagPtrs[i] = LocalTypeHandler.DupPtr(&LocalTypeHandler, data, TagDescriptor ->ElemCount); + Icc ->TagPtrs[i] = LocalTypeHandler.DupPtr(&LocalTypeHandler, data, TagDescriptor ->ElemCount); if (Icc ->TagPtrs[i] == NULL) { @@ -1596,10 +1657,16 @@ _cmsTagSignature2String(SigString, sig); cmsSignalError(Icc ->ContextID, cmsERROR_CORRUPTION_DETECTED, "Malformed struct in type '%s' for tag '%s'", TypeString, SigString); - return FALSE; + goto Error; } + _cmsUnlockMutex(Icc->ContextID, Icc ->UsrMutex); return TRUE; + +Error: + _cmsUnlockMutex(Icc->ContextID, Icc ->UsrMutex); + return FALSE; + } // Read and write raw data. The only way those function would work and keep consistence with normal read and write @@ -1620,9 +1687,11 @@ cmsUInt32Number rc; cmsUInt32Number Offset, TagSize; + if (!_cmsLockMutex(Icc->ContextID, Icc ->UsrMutex)) return 0; + // Search for given tag in ICC profile directory i = _cmsSearchTag(Icc, sig, TRUE); - if (i < 0) return 0; // Not found, return 0 + if (i < 0) goto Error; // Not found, // It is already read? if (Icc -> TagPtrs[i] == NULL) { @@ -1637,12 +1706,14 @@ if (BufferSize < TagSize) TagSize = BufferSize; - if (!Icc ->IOhandler ->Seek(Icc ->IOhandler, Offset)) return 0; - if (!Icc ->IOhandler ->Read(Icc ->IOhandler, data, 1, TagSize)) return 0; + if (!Icc ->IOhandler ->Seek(Icc ->IOhandler, Offset)) goto Error; + if (!Icc ->IOhandler ->Read(Icc ->IOhandler, data, 1, TagSize)) goto Error; + _cmsUnlockMutex(Icc->ContextID, Icc ->UsrMutex); return TagSize; } + _cmsUnlockMutex(Icc->ContextID, Icc ->UsrMutex); return Icc ->TagSizes[i]; } @@ -1658,16 +1729,22 @@ memmove(data, Icc ->TagPtrs[i], TagSize); + _cmsUnlockMutex(Icc->ContextID, Icc ->UsrMutex); return TagSize; } + _cmsUnlockMutex(Icc->ContextID, Icc ->UsrMutex); return Icc ->TagSizes[i]; } // Already readed, or previously set by cmsWriteTag(). We need to serialize that // data to raw in order to maintain consistency. + + _cmsUnlockMutex(Icc->ContextID, Icc ->UsrMutex); Object = cmsReadTag(hProfile, sig); - if (Object == NULL) return 0; + if (!_cmsLockMutex(Icc->ContextID, Icc ->UsrMutex)) return 0; + + if (Object == NULL) goto Error; // Now we need to serialize to a memory block: just use a memory iohandler @@ -1676,17 +1753,18 @@ } else{ MemIO = cmsOpenIOhandlerFromMem(cmsGetProfileContextID(hProfile), data, BufferSize, "w"); } - if (MemIO == NULL) return 0; + if (MemIO == NULL) goto Error; // Obtain type handling for the tag TypeHandler = Icc ->TagTypeHandlers[i]; - TagDescriptor = _cmsGetTagDescriptor(sig); + TagDescriptor = _cmsGetTagDescriptor(Icc-> ContextID, sig); if (TagDescriptor == NULL) { cmsCloseIOhandler(MemIO); - return 0; + goto Error; } + + if (TypeHandler == NULL) goto Error; - // FIXME: No handling for TypeHandler == NULL here? // Serialize LocalTypeHandler = *TypeHandler; LocalTypeHandler.ContextID = Icc ->ContextID; @@ -1694,19 +1772,24 @@ if (!_cmsWriteTypeBase(MemIO, TypeHandler ->Signature)) { cmsCloseIOhandler(MemIO); - return 0; + goto Error; } if (!LocalTypeHandler.WritePtr(&LocalTypeHandler, MemIO, Object, TagDescriptor ->ElemCount)) { cmsCloseIOhandler(MemIO); - return 0; + goto Error; } // Get Size and close rc = MemIO ->Tell(MemIO); cmsCloseIOhandler(MemIO); // Ignore return code this time + _cmsUnlockMutex(Icc->ContextID, Icc ->UsrMutex); return rc; + +Error: + _cmsUnlockMutex(Icc->ContextID, Icc ->UsrMutex); + return 0; } // Similar to the anterior. This function allows to write directly to the ICC profile any data, without @@ -1718,7 +1801,12 @@ _cmsICCPROFILE* Icc = (_cmsICCPROFILE*) hProfile; int i; - if (!_cmsNewTag(Icc, sig, &i)) return FALSE; + if (!_cmsLockMutex(Icc->ContextID, Icc ->UsrMutex)) return 0; + + if (!_cmsNewTag(Icc, sig, &i)) { + _cmsUnlockMutex(Icc->ContextID, Icc ->UsrMutex); + return FALSE; + } // Mark the tag as being written as RAW Icc ->TagSaveAsRaw[i] = TRUE; @@ -1729,6 +1817,7 @@ Icc ->TagPtrs[i] = _cmsDupMem(Icc ->ContextID, data, Size); Icc ->TagSizes[i] = Size; + _cmsUnlockMutex(Icc->ContextID, Icc ->UsrMutex); return TRUE; } @@ -1738,7 +1827,12 @@ _cmsICCPROFILE* Icc = (_cmsICCPROFILE*) hProfile; int i; - if (!_cmsNewTag(Icc, sig, &i)) return FALSE; + if (!_cmsLockMutex(Icc->ContextID, Icc ->UsrMutex)) return FALSE; + + if (!_cmsNewTag(Icc, sig, &i)) { + _cmsUnlockMutex(Icc->ContextID, Icc ->UsrMutex); + return FALSE; + } // Keep necessary information Icc ->TagSaveAsRaw[i] = FALSE; @@ -1749,6 +1843,7 @@ Icc ->TagSizes[i] = 0; Icc ->TagOffsets[i] = 0; + _cmsUnlockMutex(Icc->ContextID, Icc ->UsrMutex); return TRUE; } diff -Nru lcms2-2.5/src/cmsio1.c lcms2-2.6/src/cmsio1.c --- lcms2-2.5/src/cmsio1.c 2013-06-27 16:01:28.000000000 +0000 +++ lcms2-2.6/src/cmsio1.c 2014-03-17 16:09:30.000000000 +0000 @@ -305,7 +305,8 @@ // Read and create a BRAND NEW MPE LUT from a given profile. All stuff dependent of version, etc -// is adjusted here in order to create a LUT that takes care of all those details +// is adjusted here in order to create a LUT that takes care of all those details. +// We add intent = -1 as a way to read matrix shaper always, no matter of other LUT cmsPipeline* _cmsReadInputLUT(cmsHPROFILE hProfile, int Intent) { cmsTagTypeSignature OriginalType; @@ -335,49 +336,54 @@ return Lut; } - if (cmsIsTag(hProfile, tagFloat)) { // Float tag takes precedence + // This is an attempt to reuse this funtion to retrieve the matrix-shaper as pipeline no + // matter other LUT are present and have precedence. Intent = -1 means just this. + if (Intent != -1) { + + if (cmsIsTag(hProfile, tagFloat)) { // Float tag takes precedence + + // Floating point LUT are always V4, but the encoding range is no + // longer 0..1.0, so we need to add an stage depending on the color space + return _cmsReadFloatInputTag(hProfile, tagFloat); + } - // Floating point LUT are always V4, but the encoding range is no - // longer 0..1.0, so we need to add an stage depending on the color space - return _cmsReadFloatInputTag(hProfile, tagFloat); - } + // Revert to perceptual if no tag is found + if (!cmsIsTag(hProfile, tag16)) { + tag16 = Device2PCS16[0]; + } - // Revert to perceptual if no tag is found - if (!cmsIsTag(hProfile, tag16)) { - tag16 = Device2PCS16[0]; - } + if (cmsIsTag(hProfile, tag16)) { // Is there any LUT-Based table? - if (cmsIsTag(hProfile, tag16)) { // Is there any LUT-Based table? + // Check profile version and LUT type. Do the necessary adjustments if needed - // Check profile version and LUT type. Do the necessary adjustments if needed + // First read the tag + cmsPipeline* Lut = (cmsPipeline*) cmsReadTag(hProfile, tag16); + if (Lut == NULL) return NULL; - // First read the tag - cmsPipeline* Lut = (cmsPipeline*) cmsReadTag(hProfile, tag16); - if (Lut == NULL) return NULL; + // After reading it, we have now info about the original type + OriginalType = _cmsGetTagTrueType(hProfile, tag16); - // After reading it, we have now info about the original type - OriginalType = _cmsGetTagTrueType(hProfile, tag16); + // The profile owns the Lut, so we need to copy it + Lut = cmsPipelineDup(Lut); - // The profile owns the Lut, so we need to copy it - Lut = cmsPipelineDup(Lut); + // We need to adjust data only for Lab16 on output + if (OriginalType != cmsSigLut16Type || cmsGetPCS(hProfile) != cmsSigLabData) + return Lut; - // We need to adjust data only for Lab16 on output - if (OriginalType != cmsSigLut16Type || cmsGetPCS(hProfile) != cmsSigLabData) - return Lut; - - // If the input is Lab, add also a conversion at the begin - if (cmsGetColorSpace(hProfile) == cmsSigLabData && - !cmsPipelineInsertStage(Lut, cmsAT_BEGIN, _cmsStageAllocLabV4ToV2(ContextID))) - goto Error; + // If the input is Lab, add also a conversion at the begin + if (cmsGetColorSpace(hProfile) == cmsSigLabData && + !cmsPipelineInsertStage(Lut, cmsAT_BEGIN, _cmsStageAllocLabV4ToV2(ContextID))) + goto Error; - // Add a matrix for conversion V2 to V4 Lab PCS - if (!cmsPipelineInsertStage(Lut, cmsAT_END, _cmsStageAllocLabV2ToV4(ContextID))) - goto Error; + // Add a matrix for conversion V2 to V4 Lab PCS + if (!cmsPipelineInsertStage(Lut, cmsAT_END, _cmsStageAllocLabV2ToV4(ContextID))) + goto Error; - return Lut; + return Lut; Error: - cmsPipelineFree(Lut); - return NULL; + cmsPipelineFree(Lut); + return NULL; + } } // Lut was not found, try to create a matrix-shaper @@ -522,7 +528,7 @@ _cmsStageCLutData* CLUT = (_cmsStageCLutData*) Stage ->Data; CLUT ->Params->dwFlags |= CMS_LERP_FLAGS_TRILINEAR; - _cmsSetInterpolationRoutine(CLUT ->Params); + _cmsSetInterpolationRoutine(Lut->ContextID, CLUT ->Params); } } } @@ -580,54 +586,58 @@ cmsTagSignature tagFloat = PCS2DeviceFloat[Intent]; cmsContext ContextID = cmsGetProfileContextID(hProfile); - if (cmsIsTag(hProfile, tagFloat)) { // Float tag takes precedence - // Floating point LUT are always V4 - return _cmsReadFloatOutputTag(hProfile, tagFloat); - } + if (Intent != -1) { - // Revert to perceptual if no tag is found - if (!cmsIsTag(hProfile, tag16)) { - tag16 = PCS2Device16[0]; - } + if (cmsIsTag(hProfile, tagFloat)) { // Float tag takes precedence - if (cmsIsTag(hProfile, tag16)) { // Is there any LUT-Based table? + // Floating point LUT are always V4 + return _cmsReadFloatOutputTag(hProfile, tagFloat); + } - // Check profile version and LUT type. Do the necessary adjustments if needed + // Revert to perceptual if no tag is found + if (!cmsIsTag(hProfile, tag16)) { + tag16 = PCS2Device16[0]; + } - // First read the tag - cmsPipeline* Lut = (cmsPipeline*) cmsReadTag(hProfile, tag16); - if (Lut == NULL) return NULL; + if (cmsIsTag(hProfile, tag16)) { // Is there any LUT-Based table? - // After reading it, we have info about the original type - OriginalType = _cmsGetTagTrueType(hProfile, tag16); + // Check profile version and LUT type. Do the necessary adjustments if needed - // The profile owns the Lut, so we need to copy it - Lut = cmsPipelineDup(Lut); - if (Lut == NULL) return NULL; + // First read the tag + cmsPipeline* Lut = (cmsPipeline*) cmsReadTag(hProfile, tag16); + if (Lut == NULL) return NULL; - // Now it is time for a controversial stuff. I found that for 3D LUTS using - // Lab used as indexer space, trilinear interpolation should be used - if (cmsGetPCS(hProfile) == cmsSigLabData) - ChangeInterpolationToTrilinear(Lut); + // After reading it, we have info about the original type + OriginalType = _cmsGetTagTrueType(hProfile, tag16); - // We need to adjust data only for Lab and Lut16 type - if (OriginalType != cmsSigLut16Type || cmsGetPCS(hProfile) != cmsSigLabData) - return Lut; + // The profile owns the Lut, so we need to copy it + Lut = cmsPipelineDup(Lut); + if (Lut == NULL) return NULL; - // Add a matrix for conversion V4 to V2 Lab PCS - if (!cmsPipelineInsertStage(Lut, cmsAT_BEGIN, _cmsStageAllocLabV4ToV2(ContextID))) - goto Error; + // Now it is time for a controversial stuff. I found that for 3D LUTS using + // Lab used as indexer space, trilinear interpolation should be used + if (cmsGetPCS(hProfile) == cmsSigLabData) + ChangeInterpolationToTrilinear(Lut); - // If the output is Lab, add also a conversion at the end - if (cmsGetColorSpace(hProfile) == cmsSigLabData) - if (!cmsPipelineInsertStage(Lut, cmsAT_END, _cmsStageAllocLabV2ToV4(ContextID))) + // We need to adjust data only for Lab and Lut16 type + if (OriginalType != cmsSigLut16Type || cmsGetPCS(hProfile) != cmsSigLabData) + return Lut; + + // Add a matrix for conversion V4 to V2 Lab PCS + if (!cmsPipelineInsertStage(Lut, cmsAT_BEGIN, _cmsStageAllocLabV4ToV2(ContextID))) goto Error; - return Lut; + // If the output is Lab, add also a conversion at the end + if (cmsGetColorSpace(hProfile) == cmsSigLabData) + if (!cmsPipelineInsertStage(Lut, cmsAT_END, _cmsStageAllocLabV2ToV4(ContextID))) + goto Error; + + return Lut; Error: - cmsPipelineFree(Lut); - return NULL; + cmsPipelineFree(Lut); + return NULL; + } } // Lut not found, try to create a matrix-shaper @@ -753,7 +763,7 @@ // Now it is time for a controversial stuff. I found that for 3D LUTS using // Lab used as indexer space, trilinear interpolation should be used - if (cmsGetColorSpace(hProfile) == cmsSigLabData) + if (cmsGetPCS(hProfile) == cmsSigLabData) ChangeInterpolationToTrilinear(Lut); // After reading it, we have info about the original type @@ -764,12 +774,12 @@ // Here it is possible to get Lab on both sides - if (cmsGetPCS(hProfile) == cmsSigLabData) { + if (cmsGetColorSpace(hProfile) == cmsSigLabData) { if(!cmsPipelineInsertStage(Lut, cmsAT_BEGIN, _cmsStageAllocLabV4ToV2(ContextID))) goto Error2; } - if (cmsGetColorSpace(hProfile) == cmsSigLabData) { + if (cmsGetPCS(hProfile) == cmsSigLabData) { if(!cmsPipelineInsertStage(Lut, cmsAT_END, _cmsStageAllocLabV2ToV4(ContextID))) goto Error2; } diff -Nru lcms2-2.5/src/cmsopt.c lcms2-2.6/src/cmsopt.c --- lcms2-2.5/src/cmsopt.c 2013-06-27 16:01:28.000000000 +0000 +++ lcms2-2.6/src/cmsopt.c 2014-03-17 16:09:30.000000000 +0000 @@ -512,8 +512,14 @@ for (i=0; i < nOuts; i++) { cmsToneCurve* InversePostLin = cmsReverseToneCurve(Curves[i]); - WhiteOut[i] = cmsEvalToneCurve16(InversePostLin, WhitePointOut[i]); - cmsFreeToneCurve(InversePostLin); + if (InversePostLin == NULL) { + WhiteOut[i] = WhitePointOut[i]; + + } else { + + WhiteOut[i] = cmsEvalToneCurve16(InversePostLin, WhitePointOut[i]); + cmsFreeToneCurve(InversePostLin); + } } } else { @@ -1633,44 +1639,102 @@ }; // The linked list head -static _cmsOptimizationCollection* OptimizationCollection = DefaultOptimization; +_cmsOptimizationPluginChunkType _cmsOptimizationPluginChunk = { NULL }; + + +// Duplicates the zone of memory used by the plug-in in the new context +static +void DupPluginOptimizationList(struct _cmsContext_struct* ctx, + const struct _cmsContext_struct* src) +{ + _cmsOptimizationPluginChunkType newHead = { NULL }; + _cmsOptimizationCollection* entry; + _cmsOptimizationCollection* Anterior = NULL; + _cmsOptimizationPluginChunkType* head = (_cmsOptimizationPluginChunkType*) src->chunks[OptimizationPlugin]; + + _cmsAssert(ctx != NULL); + _cmsAssert(head != NULL); + + // Walk the list copying all nodes + for (entry = head->OptimizationCollection; + entry != NULL; + entry = entry ->Next) { + + _cmsOptimizationCollection *newEntry = ( _cmsOptimizationCollection *) _cmsSubAllocDup(ctx ->MemPool, entry, sizeof(_cmsOptimizationCollection)); + + if (newEntry == NULL) + return; + + // We want to keep the linked list order, so this is a little bit tricky + newEntry -> Next = NULL; + if (Anterior) + Anterior -> Next = newEntry; + + Anterior = newEntry; + + if (newHead.OptimizationCollection == NULL) + newHead.OptimizationCollection = newEntry; + } + + ctx ->chunks[OptimizationPlugin] = _cmsSubAllocDup(ctx->MemPool, &newHead, sizeof(_cmsOptimizationPluginChunkType)); +} + +void _cmsAllocOptimizationPluginChunk(struct _cmsContext_struct* ctx, + const struct _cmsContext_struct* src) +{ + if (src != NULL) { + + // Copy all linked list + DupPluginOptimizationList(ctx, src); + } + else { + static _cmsOptimizationPluginChunkType OptimizationPluginChunkType = { NULL }; + ctx ->chunks[OptimizationPlugin] = _cmsSubAllocDup(ctx ->MemPool, &OptimizationPluginChunkType, sizeof(_cmsOptimizationPluginChunkType)); + } +} + // Register new ways to optimize -cmsBool _cmsRegisterOptimizationPlugin(cmsContext id, cmsPluginBase* Data) +cmsBool _cmsRegisterOptimizationPlugin(cmsContext ContextID, cmsPluginBase* Data) { cmsPluginOptimization* Plugin = (cmsPluginOptimization*) Data; + _cmsOptimizationPluginChunkType* ctx = ( _cmsOptimizationPluginChunkType*) _cmsContextGetClientChunk(ContextID, OptimizationPlugin); _cmsOptimizationCollection* fl; if (Data == NULL) { - OptimizationCollection = DefaultOptimization; + ctx->OptimizationCollection = NULL; return TRUE; } // Optimizer callback is required if (Plugin ->OptimizePtr == NULL) return FALSE; - fl = (_cmsOptimizationCollection*) _cmsPluginMalloc(id, sizeof(_cmsOptimizationCollection)); + fl = (_cmsOptimizationCollection*) _cmsPluginMalloc(ContextID, sizeof(_cmsOptimizationCollection)); if (fl == NULL) return FALSE; // Copy the parameters fl ->OptimizePtr = Plugin ->OptimizePtr; // Keep linked list - fl ->Next = OptimizationCollection; - OptimizationCollection = fl; + fl ->Next = ctx->OptimizationCollection; + + // Set the head + ctx ->OptimizationCollection = fl; // All is ok return TRUE; } // The entry point for LUT optimization -cmsBool _cmsOptimizePipeline(cmsPipeline** PtrLut, +cmsBool _cmsOptimizePipeline(cmsContext ContextID, + cmsPipeline** PtrLut, int Intent, cmsUInt32Number* InputFormat, cmsUInt32Number* OutputFormat, cmsUInt32Number* dwFlags) { + _cmsOptimizationPluginChunkType* ctx = ( _cmsOptimizationPluginChunkType*) _cmsContextGetClientChunk(ContextID, OptimizationPlugin); _cmsOptimizationCollection* Opts; cmsBool AnySuccess = FALSE; @@ -1700,8 +1764,8 @@ if (*dwFlags & cmsFLAGS_NOOPTIMIZE) return FALSE; - // Try built-in optimizations and plug-in - for (Opts = OptimizationCollection; + // Try plug-in optimizations + for (Opts = ctx->OptimizationCollection; Opts != NULL; Opts = Opts ->Next) { @@ -1712,6 +1776,17 @@ } } + // Try built-in optimizations + for (Opts = DefaultOptimization; + Opts != NULL; + Opts = Opts ->Next) { + + if (Opts ->OptimizePtr(PtrLut, Intent, InputFormat, OutputFormat, dwFlags)) { + + return TRUE; + } + } + // Only simple optimizations succeeded return AnySuccess; } diff -Nru lcms2-2.5/src/cmspack.c lcms2-2.6/src/cmspack.c --- lcms2-2.5/src/cmspack.c 2013-06-27 16:01:28.000000000 +0000 +++ lcms2-2.6/src/cmspack.c 2014-03-17 16:09:30.000000000 +0000 @@ -854,6 +854,42 @@ } } +// This is a conversion of XYZ float to 16 bits +static +cmsUInt8Number* UnrollXYZFloatTo16(register _cmsTRANSFORM* info, + register cmsUInt16Number wIn[], + register cmsUInt8Number* accum, + register cmsUInt32Number Stride) +{ + if (T_PLANAR(info -> InputFormat)) { + + cmsFloat32Number* Pt = (cmsFloat32Number*) accum; + cmsCIEXYZ XYZ; + + XYZ.X = Pt[0]; + XYZ.Y = Pt[Stride]; + XYZ.Z = Pt[Stride*2]; + cmsFloat2XYZEncoded(wIn, &XYZ); + + return accum + sizeof(cmsFloat32Number); + + } + + else { + cmsFloat32Number* Pt = (cmsFloat32Number*) accum; + cmsCIEXYZ XYZ; + + XYZ.X = Pt[0]; + XYZ.Y = Pt[1]; + XYZ.Z = Pt[2]; + cmsFloat2XYZEncoded(wIn, &XYZ); + + accum += 3 * sizeof(cmsFloat32Number) + T_EXTRA(info ->InputFormat) * sizeof(cmsFloat32Number); + + return accum; + } +} + // Check if space is marked as ink cmsINLINE cmsBool IsInkSpace(cmsUInt32Number Type) { @@ -2305,6 +2341,39 @@ } static +cmsUInt8Number* PackXYZFloatFrom16(register _cmsTRANSFORM* Info, + register cmsUInt16Number wOut[], + register cmsUInt8Number* output, + register cmsUInt32Number Stride) +{ + if (T_PLANAR(Info -> OutputFormat)) { + + cmsCIEXYZ XYZ; + cmsFloat32Number* Out = (cmsFloat32Number*) output; + cmsXYZEncoded2Float(&XYZ, wOut); + + Out[0] = (cmsFloat32Number) XYZ.X; + Out[Stride] = (cmsFloat32Number) XYZ.Y; + Out[Stride*2] = (cmsFloat32Number) XYZ.Z; + + return output + sizeof(cmsFloat32Number); + + } + else { + + cmsCIEXYZ XYZ; + cmsFloat32Number* Out = (cmsFloat32Number*) output; + cmsXYZEncoded2Float(&XYZ, wOut); + + Out[0] = (cmsFloat32Number) XYZ.X; + Out[1] = (cmsFloat32Number) XYZ.Y; + Out[2] = (cmsFloat32Number) XYZ.Z; + + return output + (3 * sizeof(cmsFloat32Number) + T_EXTRA(Info ->OutputFormat) * sizeof(cmsFloat32Number)); + } +} + +static cmsUInt8Number* PackDoubleFrom16(register _cmsTRANSFORM* info, register cmsUInt16Number wOut[], register cmsUInt8Number* output, @@ -2864,6 +2933,7 @@ { TYPE_Lab_DBL, ANYPLANAR|ANYEXTRA, UnrollLabDoubleTo16}, { TYPE_XYZ_DBL, ANYPLANAR|ANYEXTRA, UnrollXYZDoubleTo16}, { TYPE_Lab_FLT, ANYPLANAR|ANYEXTRA, UnrollLabFloatTo16}, + { TYPE_XYZ_FLT, ANYPLANAR|ANYEXTRA, UnrollXYZFloatTo16}, { TYPE_GRAY_DBL, 0, UnrollDouble1Chan}, { FLOAT_SH(1)|BYTES_SH(0), ANYCHANNELS|ANYPLANAR|ANYSWAPFIRST|ANYFLAVOR| ANYSWAP|ANYEXTRA|ANYSPACE, UnrollDoubleTo16}, @@ -2998,6 +3068,7 @@ { TYPE_XYZ_DBL, ANYPLANAR|ANYEXTRA, PackXYZDoubleFrom16}, { TYPE_Lab_FLT, ANYPLANAR|ANYEXTRA, PackLabFloatFrom16}, + { TYPE_XYZ_FLT, ANYPLANAR|ANYEXTRA, PackXYZFloatFrom16}, { FLOAT_SH(1)|BYTES_SH(0), ANYFLAVOR|ANYSWAPFIRST|ANYSWAP| ANYCHANNELS|ANYPLANAR|ANYEXTRA|ANYSPACE, PackDoubleFrom16}, @@ -3153,40 +3224,98 @@ } cmsFormattersFactoryList; -static cmsFormattersFactoryList* FactoryList = NULL; +_cmsFormattersPluginChunkType _cmsFormattersPluginChunk = { NULL }; + + +// Duplicates the zone of memory used by the plug-in in the new context +static +void DupFormatterFactoryList(struct _cmsContext_struct* ctx, + const struct _cmsContext_struct* src) +{ + _cmsFormattersPluginChunkType newHead = { NULL }; + cmsFormattersFactoryList* entry; + cmsFormattersFactoryList* Anterior = NULL; + _cmsFormattersPluginChunkType* head = (_cmsFormattersPluginChunkType*) src->chunks[FormattersPlugin]; + + _cmsAssert(head != NULL); + + // Walk the list copying all nodes + for (entry = head->FactoryList; + entry != NULL; + entry = entry ->Next) { + + cmsFormattersFactoryList *newEntry = ( cmsFormattersFactoryList *) _cmsSubAllocDup(ctx ->MemPool, entry, sizeof(cmsFormattersFactoryList)); + + if (newEntry == NULL) + return; + + // We want to keep the linked list order, so this is a little bit tricky + newEntry -> Next = NULL; + if (Anterior) + Anterior -> Next = newEntry; + + Anterior = newEntry; + + if (newHead.FactoryList == NULL) + newHead.FactoryList = newEntry; + } + + ctx ->chunks[FormattersPlugin] = _cmsSubAllocDup(ctx->MemPool, &newHead, sizeof(_cmsFormattersPluginChunkType)); +} + +// The interpolation plug-in memory chunk allocator/dup +void _cmsAllocFormattersPluginChunk(struct _cmsContext_struct* ctx, + const struct _cmsContext_struct* src) +{ + _cmsAssert(ctx != NULL); + + if (src != NULL) { + + // Duplicate the LIST + DupFormatterFactoryList(ctx, src); + } + else { + static _cmsFormattersPluginChunkType FormattersPluginChunk = { NULL }; + ctx ->chunks[FormattersPlugin] = _cmsSubAllocDup(ctx ->MemPool, &FormattersPluginChunk, sizeof(_cmsFormattersPluginChunkType)); + } +} + // Formatters management -cmsBool _cmsRegisterFormattersPlugin(cmsContext id, cmsPluginBase* Data) +cmsBool _cmsRegisterFormattersPlugin(cmsContext ContextID, cmsPluginBase* Data) { + _cmsFormattersPluginChunkType* ctx = ( _cmsFormattersPluginChunkType*) _cmsContextGetClientChunk(ContextID, FormattersPlugin); cmsPluginFormatters* Plugin = (cmsPluginFormatters*) Data; cmsFormattersFactoryList* fl ; - // Reset + // Reset to built-in defaults if (Data == NULL) { - FactoryList = NULL; + ctx ->FactoryList = NULL; return TRUE; } - fl = (cmsFormattersFactoryList*) _cmsPluginMalloc(id, sizeof(cmsFormattersFactoryList)); + fl = (cmsFormattersFactoryList*) _cmsPluginMalloc(ContextID, sizeof(cmsFormattersFactoryList)); if (fl == NULL) return FALSE; fl ->Factory = Plugin ->FormattersFactory; - fl ->Next = FactoryList; - FactoryList = fl; + fl ->Next = ctx -> FactoryList; + ctx ->FactoryList = fl; return TRUE; } -cmsFormatter _cmsGetFormatter(cmsUInt32Number Type, // Specific type, i.e. TYPE_RGB_8 +cmsFormatter _cmsGetFormatter(cmsContext ContextID, + cmsUInt32Number Type, // Specific type, i.e. TYPE_RGB_8 cmsFormatterDirection Dir, cmsUInt32Number dwFlags) { + _cmsFormattersPluginChunkType* ctx = ( _cmsFormattersPluginChunkType*) _cmsContextGetClientChunk(ContextID, FormattersPlugin); cmsFormattersFactoryList* f; - for (f = FactoryList; f != NULL; f = f ->Next) { + for (f =ctx->FactoryList; f != NULL; f = f ->Next) { cmsFormatter fn = f ->Factory(Type, Dir, dwFlags); if (fn.Fmt16 != NULL) return fn; diff -Nru lcms2-2.5/src/cmsplugin.c lcms2-2.6/src/cmsplugin.c --- lcms2-2.5/src/cmsplugin.c 2013-07-01 06:59:05.000000000 +0000 +++ lcms2-2.6/src/cmsplugin.c 2014-03-17 16:09:30.000000000 +0000 @@ -515,22 +515,31 @@ // Plugin memory management ------------------------------------------------------------------------------------------------- -static _cmsSubAllocator* PluginPool = NULL; - // Specialized malloc for plug-ins, that is freed upon exit. -void* _cmsPluginMalloc(cmsContext id, cmsUInt32Number size) +void* _cmsPluginMalloc(cmsContext ContextID, cmsUInt32Number size) { - if (PluginPool == NULL) - PluginPool = _cmsCreateSubAlloc(id, 4*1024); + struct _cmsContext_struct* ctx = _cmsGetContext(ContextID); + + if (ctx ->MemPool == NULL) { + + if (ContextID == NULL) { + + ctx->MemPool = _cmsCreateSubAlloc(0, 2*1024); + } + else { + cmsSignalError(ContextID, cmsERROR_CORRUPTION_DETECTED, "NULL memory pool on context"); + return NULL; + } + } - return _cmsSubAlloc(PluginPool, size); + return _cmsSubAlloc(ctx->MemPool, size); } // Main plug-in dispatcher cmsBool CMSEXPORT cmsPlugin(void* Plug_in) { - return cmsPluginTHR(NULL, Plug_in); + return cmsPluginTHR(NULL, Plug_in); } cmsBool CMSEXPORT cmsPluginTHR(cmsContext id, void* Plug_in) @@ -542,12 +551,12 @@ Plugin = Plugin -> Next) { if (Plugin -> Magic != cmsPluginMagicNumber) { - cmsSignalError(0, cmsERROR_UNKNOWN_EXTENSION, "Unrecognized plugin"); + cmsSignalError(id, cmsERROR_UNKNOWN_EXTENSION, "Unrecognized plugin"); return FALSE; } if (Plugin ->ExpectedVersion > LCMS_VERSION) { - cmsSignalError(0, cmsERROR_UNKNOWN_EXTENSION, "plugin needs Little CMS %d, current version is %d", + cmsSignalError(id, cmsERROR_UNKNOWN_EXTENSION, "plugin needs Little CMS %d, current version is %d", Plugin ->ExpectedVersion, LCMS_VERSION); return FALSE; } @@ -555,11 +564,11 @@ switch (Plugin -> Type) { case cmsPluginMemHandlerSig: - if (!_cmsRegisterMemHandlerPlugin(Plugin)) return FALSE; + if (!_cmsRegisterMemHandlerPlugin(id, Plugin)) return FALSE; break; case cmsPluginInterpolationSig: - if (!_cmsRegisterInterpPlugin(Plugin)) return FALSE; + if (!_cmsRegisterInterpPlugin(id, Plugin)) return FALSE; break; case cmsPluginTagTypeSig: @@ -594,8 +603,12 @@ if (!_cmsRegisterTransformPlugin(id, Plugin)) return FALSE; break; + case cmsPluginMutexSig: + if (!_cmsRegisterMutexPlugin(id, Plugin)) return FALSE; + break; + default: - cmsSignalError(0, cmsERROR_UNKNOWN_EXTENSION, "Unrecognized plugin type '%X'", Plugin -> Type); + cmsSignalError(id, cmsERROR_UNKNOWN_EXTENSION, "Unrecognized plugin type '%X'", Plugin -> Type); return FALSE; } } @@ -608,19 +621,337 @@ // Revert all plug-ins to default void CMSEXPORT cmsUnregisterPlugins(void) { - _cmsRegisterMemHandlerPlugin(NULL); - _cmsRegisterInterpPlugin(NULL); - _cmsRegisterTagTypePlugin(NULL, NULL); - _cmsRegisterTagPlugin(NULL, NULL); - _cmsRegisterFormattersPlugin(NULL, NULL); - _cmsRegisterRenderingIntentPlugin(NULL, NULL); - _cmsRegisterParametricCurvesPlugin(NULL, NULL); - _cmsRegisterMultiProcessElementPlugin(NULL, NULL); - _cmsRegisterOptimizationPlugin(NULL, NULL); - _cmsRegisterTransformPlugin(NULL, NULL); + cmsUnregisterPluginsTHR(NULL); +} + + +// The Global storage for system context. This is the one and only global variable +// pointers structure. All global vars are referenced here. +static struct _cmsContext_struct globalContext = { + + NULL, // Not in the linked list + NULL, // No suballocator + { + NULL, // UserPtr, + &_cmsLogErrorChunk, // Logger, + &_cmsAlarmCodesChunk, // AlarmCodes, + &_cmsAdaptationStateChunk, // AdaptationState, + &_cmsMemPluginChunk, // MemPlugin, + &_cmsInterpPluginChunk, // InterpPlugin, + &_cmsCurvesPluginChunk, // CurvesPlugin, + &_cmsFormattersPluginChunk, // FormattersPlugin, + &_cmsTagTypePluginChunk, // TagTypePlugin, + &_cmsTagPluginChunk, // TagPlugin, + &_cmsIntentsPluginChunk, // IntentPlugin, + &_cmsMPETypePluginChunk, // MPEPlugin, + &_cmsOptimizationPluginChunk, // OptimizationPlugin, + &_cmsTransformPluginChunk, // TransformPlugin, + &_cmsMutexPluginChunk // MutexPlugin + }, + + { NULL, NULL, NULL, NULL, NULL, NULL } // The default memory allocator is not used for context 0 +}; + + +// The context pool (linked list head) +static _cmsMutex _cmsContextPoolHeadMutex = CMS_MUTEX_INITIALIZER; +static struct _cmsContext_struct* _cmsContextPoolHead = NULL; + +// Internal, get associated pointer, with guessing. Never returns NULL. +struct _cmsContext_struct* _cmsGetContext(cmsContext ContextID) +{ + struct _cmsContext_struct* id = (struct _cmsContext_struct*) ContextID; + struct _cmsContext_struct* ctx; + + + // On 0, use global settings + if (id == NULL) + return &globalContext; + + // Search + for (ctx = _cmsContextPoolHead; + ctx != NULL; + ctx = ctx ->Next) { + + // Found it? + if (id == ctx) + return ctx; // New-style context, + } + + return &globalContext; +} + + +// Internal: get the memory area associanted with each context client +// Returns the block assigned to the specific zone. +void* _cmsContextGetClientChunk(cmsContext ContextID, _cmsMemoryClient mc) +{ + struct _cmsContext_struct* ctx; + void *ptr; + + if (mc < 0 || mc >= MemoryClientMax) { + cmsSignalError(ContextID, cmsERROR_RANGE, "Bad context client"); + return NULL; + } + + ctx = _cmsGetContext(ContextID); + ptr = ctx ->chunks[mc]; + + if (ptr != NULL) + return ptr; + + // A null ptr means no special settings for that context, and this + // reverts to Context0 globals + return globalContext.chunks[mc]; +} + + +// This function returns the given context its default pristine state, +// as no plug-ins were declared. There is no way to unregister a single +// plug-in, as a single call to cmsPluginTHR() function may register +// many different plug-ins simultaneously, then there is no way to +// identify which plug-in to unregister. +void CMSEXPORT cmsUnregisterPluginsTHR(cmsContext ContextID) +{ + _cmsRegisterMemHandlerPlugin(ContextID, NULL); + _cmsRegisterInterpPlugin(ContextID, NULL); + _cmsRegisterTagTypePlugin(ContextID, NULL); + _cmsRegisterTagPlugin(ContextID, NULL); + _cmsRegisterFormattersPlugin(ContextID, NULL); + _cmsRegisterRenderingIntentPlugin(ContextID, NULL); + _cmsRegisterParametricCurvesPlugin(ContextID, NULL); + _cmsRegisterMultiProcessElementPlugin(ContextID, NULL); + _cmsRegisterOptimizationPlugin(ContextID, NULL); + _cmsRegisterTransformPlugin(ContextID, NULL); + _cmsRegisterMutexPlugin(ContextID, NULL); +} + + +// Returns the memory manager plug-in, if any, from the Plug-in bundle +static +cmsPluginMemHandler* _cmsFindMemoryPlugin(void* PluginBundle) +{ + cmsPluginBase* Plugin; + + for (Plugin = (cmsPluginBase*) PluginBundle; + Plugin != NULL; + Plugin = Plugin -> Next) { + + if (Plugin -> Magic == cmsPluginMagicNumber && + Plugin -> ExpectedVersion <= LCMS_VERSION && + Plugin -> Type == cmsPluginMemHandlerSig) { + + // Found! + return (cmsPluginMemHandler*) Plugin; + } + } + + // Nope, revert to defaults + return NULL; +} + + +// Creates a new context with optional associated plug-ins. Caller may also specify an optional pointer to user-defined +// data that will be forwarded to plug-ins and logger. +cmsContext CMSEXPORT cmsCreateContext(void* Plugin, void* UserData) +{ + struct _cmsContext_struct* ctx; + struct _cmsContext_struct fakeContext; + + _cmsInstallAllocFunctions(_cmsFindMemoryPlugin(Plugin), &fakeContext.DefaultMemoryManager); + + fakeContext.chunks[UserPtr] = UserData; + fakeContext.chunks[MemPlugin] = &fakeContext.DefaultMemoryManager; + + // Create the context structure. + ctx = (struct _cmsContext_struct*) _cmsMalloc(&fakeContext, sizeof(struct _cmsContext_struct)); + if (ctx == NULL) + return NULL; // Something very wrong happened! + + // Init the structure and the memory manager + memset(ctx, 0, sizeof(struct _cmsContext_struct)); + + // Keep memory manager + memcpy(&ctx->DefaultMemoryManager, &fakeContext.DefaultMemoryManager, sizeof(_cmsMemPluginChunk)); + + // Maintain the linked list (with proper locking) + _cmsEnterCriticalSectionPrimitive(&_cmsContextPoolHeadMutex); + ctx ->Next = _cmsContextPoolHead; + _cmsContextPoolHead = ctx; + _cmsLeaveCriticalSectionPrimitive(&_cmsContextPoolHeadMutex); + + ctx ->chunks[UserPtr] = UserData; + ctx ->chunks[MemPlugin] = &ctx->DefaultMemoryManager; + + // Now we can allocate the pool by using default memory manager + ctx ->MemPool = _cmsCreateSubAlloc(ctx, 22 * sizeof(void*)); // default size about 32 pointers + if (ctx ->MemPool == NULL) { + + cmsDeleteContext(ctx); + return NULL; + } - if (PluginPool != NULL) - _cmsSubAllocDestroy(PluginPool); + _cmsAllocLogErrorChunk(ctx, NULL); + _cmsAllocAlarmCodesChunk(ctx, NULL); + _cmsAllocAdaptationStateChunk(ctx, NULL); + _cmsAllocMemPluginChunk(ctx, NULL); + _cmsAllocInterpPluginChunk(ctx, NULL); + _cmsAllocCurvesPluginChunk(ctx, NULL); + _cmsAllocFormattersPluginChunk(ctx, NULL); + _cmsAllocTagTypePluginChunk(ctx, NULL); + _cmsAllocMPETypePluginChunk(ctx, NULL); + _cmsAllocTagPluginChunk(ctx, NULL); + _cmsAllocIntentsPluginChunk(ctx, NULL); + _cmsAllocOptimizationPluginChunk(ctx, NULL); + _cmsAllocTransformPluginChunk(ctx, NULL); + _cmsAllocMutexPluginChunk(ctx, NULL); + + // Setup the plug-ins + if (!cmsPluginTHR(ctx, Plugin)) { + + cmsDeleteContext(ctx); + return NULL; + } - PluginPool = NULL; + return (cmsContext) ctx; } + +// Duplicates a context with all associated plug-ins. +// Caller may specify an optional pointer to user-defined +// data that will be forwarded to plug-ins and logger. +cmsContext CMSEXPORT cmsDupContext(cmsContext ContextID, void* NewUserData) +{ + int i; + struct _cmsContext_struct* ctx; + const struct _cmsContext_struct* src = _cmsGetContext(ContextID); + + void* userData = (NewUserData != NULL) ? NewUserData : src -> chunks[UserPtr]; + + + ctx = (struct _cmsContext_struct*) _cmsMalloc(ContextID, sizeof(struct _cmsContext_struct)); + if (ctx == NULL) + return NULL; // Something very wrong happened + + // Setup default memory allocators + memcpy(&ctx->DefaultMemoryManager, &src->DefaultMemoryManager, sizeof(ctx->DefaultMemoryManager)); + + // Maintain the linked list + _cmsEnterCriticalSectionPrimitive(&_cmsContextPoolHeadMutex); + ctx ->Next = _cmsContextPoolHead; + _cmsContextPoolHead = ctx; + _cmsLeaveCriticalSectionPrimitive(&_cmsContextPoolHeadMutex); + + ctx ->chunks[UserPtr] = userData; + ctx ->chunks[MemPlugin] = &ctx->DefaultMemoryManager; + + ctx ->MemPool = _cmsCreateSubAlloc(ctx, 22 * sizeof(void*)); + if (ctx ->MemPool == NULL) { + + cmsDeleteContext(ctx); + return NULL; + } + + // Allocate all required chunks. + _cmsAllocLogErrorChunk(ctx, src); + _cmsAllocAlarmCodesChunk(ctx, src); + _cmsAllocAdaptationStateChunk(ctx, src); + _cmsAllocMemPluginChunk(ctx, src); + _cmsAllocInterpPluginChunk(ctx, src); + _cmsAllocCurvesPluginChunk(ctx, src); + _cmsAllocFormattersPluginChunk(ctx, src); + _cmsAllocTagTypePluginChunk(ctx, src); + _cmsAllocMPETypePluginChunk(ctx, src); + _cmsAllocTagPluginChunk(ctx, src); + _cmsAllocIntentsPluginChunk(ctx, src); + _cmsAllocOptimizationPluginChunk(ctx, src); + _cmsAllocTransformPluginChunk(ctx, src); + _cmsAllocMutexPluginChunk(ctx, src); + + // Make sure no one failed + for (i=Logger; i < MemoryClientMax; i++) { + + if (src ->chunks[i] == NULL) { + cmsDeleteContext((cmsContext) ctx); + return NULL; + } + } + + return (cmsContext) ctx; +} + + + +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. +void CMSEXPORT cmsDeleteContext(cmsContext ContextID) +{ + if (ContextID != NULL) { + + struct _cmsContext_struct* ctx = (struct _cmsContext_struct*) ContextID; + struct _cmsContext_struct fakeContext; + struct _cmsContext_struct* prev; + + memcpy(&fakeContext.DefaultMemoryManager, &ctx->DefaultMemoryManager, sizeof(ctx->DefaultMemoryManager)); + + fakeContext.chunks[UserPtr] = ctx ->chunks[UserPtr]; + fakeContext.chunks[MemPlugin] = &fakeContext.DefaultMemoryManager; + + // Get rid of plugins + cmsUnregisterPluginsTHR(ContextID); + + // Since all memory is allocated in the private pool, all what we need to do is destroy the pool + if (ctx -> MemPool != NULL) + _cmsSubAllocDestroy(ctx ->MemPool); + ctx -> MemPool = NULL; + + // Maintain list + _cmsEnterCriticalSectionPrimitive(&_cmsContextPoolHeadMutex); + if (_cmsContextPoolHead == ctx) { + + _cmsContextPoolHead = ctx->Next; + } + else { + + // Search for previous + for (prev = _cmsContextPoolHead; + prev != NULL; + prev = prev ->Next) + { + if (prev -> Next == ctx) { + prev -> Next = ctx ->Next; + break; + } + } + } + _cmsLeaveCriticalSectionPrimitive(&_cmsContextPoolHeadMutex); + + // free the memory block itself + _cmsFree(&fakeContext, ctx); + } +} + +// Returns the user data associated to the given ContextID, or NULL if no user data was attached on context creation +void* CMSEXPORT cmsGetContextUserData(cmsContext ContextID) +{ + return _cmsContextGetClientChunk(ContextID, UserPtr); +} + + diff -Nru lcms2-2.5/src/cmsps2.c lcms2-2.6/src/cmsps2.c --- lcms2-2.5/src/cmsps2.c 2013-06-27 16:01:28.000000000 +0000 +++ lcms2-2.6/src/cmsps2.c 2014-03-17 16:09:30.000000000 +0000 @@ -913,7 +913,7 @@ if (DeviceLink == NULL) return 0; dwFlags |= cmsFLAGS_FORCE_CLUT; - _cmsOptimizePipeline(&DeviceLink, Intent, &InputFormat, &OutFrm, &dwFlags); + _cmsOptimizePipeline(m->ContextID, &DeviceLink, Intent, &InputFormat, &OutFrm, &dwFlags); rc = EmitCIEBasedDEF(m, DeviceLink, Intent, &BlackPointAdaptedToD50); cmsPipelineFree(DeviceLink); @@ -1330,7 +1330,7 @@ // We need a CLUT dwFlags |= cmsFLAGS_FORCE_CLUT; - _cmsOptimizePipeline(&DeviceLink, RelativeEncodingIntent, &InFrm, &OutputFormat, &dwFlags); + _cmsOptimizePipeline(m->ContextID, &DeviceLink, RelativeEncodingIntent, &InFrm, &OutputFormat, &dwFlags); _cmsIOPrintf(m, "<<\n"); _cmsIOPrintf(m, "/ColorRenderingType 1\n"); diff -Nru lcms2-2.5/src/cmstypes.c lcms2-2.6/src/cmstypes.c --- lcms2-2.5/src/cmstypes.c 2013-06-27 16:01:28.000000000 +0000 +++ lcms2-2.6/src/cmstypes.c 2014-03-17 16:09:30.000000000 +0000 @@ -1,7 +1,7 @@ //--------------------------------------------------------------------------------- // // Little Color Management System -// Copyright (c) 1998-2011 Marti Maria Saguer +// Copyright (c) 1998-2014 Marti Maria Saguer // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the "Software"), @@ -32,7 +32,7 @@ // are no profiles holding them. The programmer can also extend this list by defining his own types // by using the appropiate plug-in. There are three types of plug ins regarding that. First type // allows to define new tags using any existing type. Next plug-in type allows to define new types -// and the third one is very specific: allows to extend the number of elements in the multiprofile +// and the third one is very specific: allows to extend the number of elements in the multiprocessing // elements special type. //-------------------------------------------------------------------------------------------------- @@ -60,54 +60,49 @@ // Helper macro to define a MPE handler. Callbacks do have a fixed naming convention #define TYPE_MPE_HANDLER(t, x) { (t), READ_FN(x), WRITE_FN(x), GenericMPEdup, GenericMPEfree, NULL, 0 } -// Register a new type handler. This routine is shared between normal types and MPE +// Register a new type handler. This routine is shared between normal types and MPE. LinkedList points to the optional list head static -cmsBool RegisterTypesPlugin(cmsContext id, cmsPluginBase* Data, _cmsTagTypeLinkedList* LinkedList, cmsUInt32Number DefaultListCount) +cmsBool RegisterTypesPlugin(cmsContext id, cmsPluginBase* Data, _cmsMemoryClient pos) { cmsPluginTagType* Plugin = (cmsPluginTagType*) Data; - _cmsTagTypeLinkedList *pt, *Anterior = NULL; + _cmsTagTypePluginChunkType* ctx = ( _cmsTagTypePluginChunkType*) _cmsContextGetClientChunk(id, pos); + _cmsTagTypeLinkedList *pt; // Calling the function with NULL as plug-in would unregister the plug in. if (Data == NULL) { - LinkedList[DefaultListCount-1].Next = NULL; + // There is no need to set free the memory, as pool is destroyed as a whole. + ctx ->TagTypes = NULL; return TRUE; } - pt = Anterior = LinkedList; - while (pt != NULL) { - - if (Plugin->Handler.Signature == pt -> Handler.Signature) { - pt ->Handler = Plugin ->Handler; // Replace old behaviour. - // Note that since no memory is allocated, unregister does not - // reset this action. - return TRUE; - } - - Anterior = pt; - pt = pt ->Next; - } - - // Registering happens in plug-in memory pool + // Registering happens in plug-in memory pool. pt = (_cmsTagTypeLinkedList*) _cmsPluginMalloc(id, sizeof(_cmsTagTypeLinkedList)); if (pt == NULL) return FALSE; pt ->Handler = Plugin ->Handler; - pt ->Next = NULL; - - if (Anterior) - Anterior -> Next = pt; + pt ->Next = ctx ->TagTypes; + ctx ->TagTypes = pt; + return TRUE; } -// Return handler for a given type or NULL if not found. Shared between normal types and MPE +// Return handler for a given type or NULL if not found. Shared between normal types and MPE. It first tries the additons +// made by plug-ins and then the built-in defaults. static -cmsTagTypeHandler* GetHandler(cmsTagTypeSignature sig, _cmsTagTypeLinkedList* LinkedList) +cmsTagTypeHandler* GetHandler(cmsTagTypeSignature sig, _cmsTagTypeLinkedList* PluginLinkedList, _cmsTagTypeLinkedList* DefaultLinkedList) { _cmsTagTypeLinkedList* pt; - for (pt = LinkedList; + for (pt = PluginLinkedList; + pt != NULL; + pt = pt ->Next) { + + if (sig == pt -> Handler.Signature) return &pt ->Handler; + } + + for (pt = DefaultLinkedList; pt != NULL; pt = pt ->Next) { @@ -134,6 +129,7 @@ return TRUE; } +// Auxiliar to read an array of wchar_t static cmsBool _cmsReadWCharArray(cmsIOHANDLER* io, cmsUInt32Number n, wchar_t* Array) { @@ -748,6 +744,8 @@ // Create memory Text = (char*) _cmsMalloc(self ->ContextID, size); + if (Text == NULL) return FALSE; + cmsMLUgetASCII(mlu, cmsNoLanguage, cmsNoCountry, Text, size); // Write it, including separator @@ -1754,7 +1752,6 @@ if (!_cmsReadUInt8Number(io, NULL)) goto Error; // Do some checking - if (InputChannels > cmsMAXCHANNELS) goto Error; if (OutputChannels > cmsMAXCHANNELS) goto Error; @@ -1795,9 +1792,16 @@ if (T == NULL) goto Error; Temp = (cmsUInt8Number*) _cmsMalloc(self ->ContextID, nTabSize); - if (Temp == NULL) goto Error; + if (Temp == NULL) { + _cmsFree(self ->ContextID, T); + goto Error; + } - if (io ->Read(io, Temp, nTabSize, 1) != 1) goto Error; + if (io ->Read(io, Temp, nTabSize, 1) != 1) { + _cmsFree(self ->ContextID, T); + _cmsFree(self ->ContextID, Temp); + goto Error; + } for (i = 0; i < nTabSize; i++) { @@ -2342,27 +2346,30 @@ // Precision can be 1 or 2 bytes if (Precision == 1) { - cmsUInt8Number v; + cmsUInt8Number v; for (i=0; i < Data ->nEntries; i++) { - if (io ->Read(io, &v, sizeof(cmsUInt8Number), 1) != 1) return NULL; - Data ->Tab.T[i] = FROM_8_TO_16(v); + if (io ->Read(io, &v, sizeof(cmsUInt8Number), 1) != 1) return NULL; + Data ->Tab.T[i] = FROM_8_TO_16(v); } } else if (Precision == 2) { - if (!_cmsReadUInt16Array(io, Data->nEntries, Data ->Tab.T)) return NULL; - } - else { - cmsSignalError(self ->ContextID, cmsERROR_UNKNOWN_EXTENSION, "Unknown precision of '%d'", Precision); - return NULL; - } - + if (!_cmsReadUInt16Array(io, Data->nEntries, Data ->Tab.T)) { + cmsStageFree(CLUT); + return NULL; + } + } + else { + cmsStageFree(CLUT); + cmsSignalError(self ->ContextID, cmsERROR_UNKNOWN_EXTENSION, "Unknown precision of '%d'", Precision); + return NULL; + } - return CLUT; + return CLUT; } static @@ -4345,7 +4352,7 @@ {TYPE_MPE_HANDLER((cmsTagTypeSignature) cmsSigCLutElemType, MPEclut), NULL }, }; -#define DEFAULT_MPE_TYPE_COUNT (sizeof(SupportedMPEtypes) / sizeof(_cmsTagTypeLinkedList)) +_cmsTagTypePluginChunkType _cmsMPETypePluginChunk = { NULL }; static cmsBool ReadMPEElem(struct _cms_typehandler_struct* self, @@ -4358,6 +4365,8 @@ cmsTagTypeHandler* TypeHandler; cmsUInt32Number nItems; cmsPipeline *NewLUT = (cmsPipeline *) Cargo; + _cmsTagTypePluginChunkType* MPETypePluginChunk = ( _cmsTagTypePluginChunkType*) _cmsContextGetClientChunk(self->ContextID, MPEPlugin); + // Take signature and channels for each element. if (!_cmsReadUInt32Number(io, (cmsUInt32Number*) &ElementSig)) return FALSE; @@ -4366,7 +4375,7 @@ if (!_cmsReadUInt32Number(io, NULL)) return FALSE; // Read diverse MPE types - TypeHandler = GetHandler((cmsTagTypeSignature) ElementSig, SupportedMPEtypes); + TypeHandler = GetHandler((cmsTagTypeSignature) ElementSig, MPETypePluginChunk ->TagTypes, SupportedMPEtypes); if (TypeHandler == NULL) { char String[5]; @@ -4443,6 +4452,7 @@ cmsPipeline* Lut = (cmsPipeline*) Ptr; cmsStage* Elem = Lut ->Elements; cmsTagTypeHandler* TypeHandler; + _cmsTagTypePluginChunkType* MPETypePluginChunk = ( _cmsTagTypePluginChunkType*) _cmsContextGetClientChunk(self->ContextID, MPEPlugin); BaseOffset = io ->Tell(io) - sizeof(_cmsTagBase); @@ -4476,7 +4486,7 @@ ElementSig = Elem ->Type; - TypeHandler = GetHandler((cmsTagTypeSignature) ElementSig, SupportedMPEtypes); + TypeHandler = GetHandler((cmsTagTypeSignature) ElementSig, MPETypePluginChunk->TagTypes, SupportedMPEtypes); if (TypeHandler == NULL) { char String[5]; @@ -5096,7 +5106,7 @@ } else { - rc = cmsDictAddEntry(hDict, NameWCS, ValueWCS, DisplayNameMLU, DisplayValueMLU); + rc = cmsDictAddEntry(hDict, NameWCS, ValueWCS, DisplayNameMLU, DisplayValueMLU); } if (NameWCS != NULL) _cmsFree(self ->ContextID, NameWCS); @@ -5253,24 +5263,95 @@ {TYPE_HANDLER(cmsSigVcgtType, vcgt), NULL } }; -#define DEFAULT_TAG_TYPE_COUNT (sizeof(SupportedTagTypes) / sizeof(_cmsTagTypeLinkedList)) + +_cmsTagTypePluginChunkType _cmsTagTypePluginChunk = { NULL }; + + + +// Duplicates the zone of memory used by the plug-in in the new context +static +void DupTagTypeList(struct _cmsContext_struct* ctx, + const struct _cmsContext_struct* src, + int loc) +{ + _cmsTagTypePluginChunkType newHead = { NULL }; + _cmsTagTypeLinkedList* entry; + _cmsTagTypeLinkedList* Anterior = NULL; + _cmsTagTypePluginChunkType* head = (_cmsTagTypePluginChunkType*) src->chunks[loc]; + + // Walk the list copying all nodes + for (entry = head->TagTypes; + entry != NULL; + entry = entry ->Next) { + + _cmsTagTypeLinkedList *newEntry = ( _cmsTagTypeLinkedList *) _cmsSubAllocDup(ctx ->MemPool, entry, sizeof(_cmsTagTypeLinkedList)); + + if (newEntry == NULL) + return; + + // We want to keep the linked list order, so this is a little bit tricky + newEntry -> Next = NULL; + if (Anterior) + Anterior -> Next = newEntry; + + Anterior = newEntry; + + if (newHead.TagTypes == NULL) + newHead.TagTypes = newEntry; + } + + ctx ->chunks[loc] = _cmsSubAllocDup(ctx->MemPool, &newHead, sizeof(_cmsTagTypePluginChunkType)); +} + + +void _cmsAllocTagTypePluginChunk(struct _cmsContext_struct* ctx, + const struct _cmsContext_struct* src) +{ + if (src != NULL) { + + // Duplicate the LIST + DupTagTypeList(ctx, src, TagTypePlugin); + } + else { + static _cmsTagTypePluginChunkType TagTypePluginChunk = { NULL }; + ctx ->chunks[TagTypePlugin] = _cmsSubAllocDup(ctx ->MemPool, &TagTypePluginChunk, sizeof(_cmsTagTypePluginChunkType)); + } +} + +void _cmsAllocMPETypePluginChunk(struct _cmsContext_struct* ctx, + const struct _cmsContext_struct* src) +{ + if (src != NULL) { + + // Duplicate the LIST + DupTagTypeList(ctx, src, MPEPlugin); + } + else { + static _cmsTagTypePluginChunkType TagTypePluginChunk = { NULL }; + ctx ->chunks[MPEPlugin] = _cmsSubAllocDup(ctx ->MemPool, &TagTypePluginChunk, sizeof(_cmsTagTypePluginChunkType)); + } + +} + // Both kind of plug-ins share same structure cmsBool _cmsRegisterTagTypePlugin(cmsContext id, cmsPluginBase* Data) { - return RegisterTypesPlugin(id, Data, SupportedTagTypes, DEFAULT_TAG_TYPE_COUNT); + return RegisterTypesPlugin(id, Data, TagTypePlugin); } cmsBool _cmsRegisterMultiProcessElementPlugin(cmsContext id, cmsPluginBase* Data) { - return RegisterTypesPlugin(id, Data, SupportedMPEtypes, DEFAULT_MPE_TYPE_COUNT); + return RegisterTypesPlugin(id, Data,MPEPlugin); } // Wrapper for tag types -cmsTagTypeHandler* _cmsGetTagTypeHandler(cmsTagTypeSignature sig) +cmsTagTypeHandler* _cmsGetTagTypeHandler(cmsContext ContextID, cmsTagTypeSignature sig) { - return GetHandler(sig, SupportedTagTypes); + _cmsTagTypePluginChunkType* ctx = ( _cmsTagTypePluginChunkType*) _cmsContextGetClientChunk(ContextID, TagTypePlugin); + + return GetHandler(sig, ctx->TagTypes, SupportedTagTypes); } // ******************************************************************************** @@ -5385,30 +5466,68 @@ cmsSigDeviceSettingsTag ==> Deprecated, useless */ -#define DEFAULT_TAG_COUNT (sizeof(SupportedTags) / sizeof(_cmsTagLinkedList)) -cmsBool _cmsRegisterTagPlugin(cmsContext id, cmsPluginBase* Data) +_cmsTagPluginChunkType _cmsTagPluginChunk = { NULL }; + + +// Duplicates the zone of memory used by the plug-in in the new context +static +void DupTagList(struct _cmsContext_struct* ctx, + const struct _cmsContext_struct* src) { - cmsPluginTag* Plugin = (cmsPluginTag*) Data; - _cmsTagLinkedList *pt, *Anterior; + _cmsTagPluginChunkType newHead = { NULL }; + _cmsTagLinkedList* entry; + _cmsTagLinkedList* Anterior = NULL; + _cmsTagPluginChunkType* head = (_cmsTagPluginChunkType*) src->chunks[TagPlugin]; + // Walk the list copying all nodes + for (entry = head->Tag; + entry != NULL; + entry = entry ->Next) { - if (Data == NULL) { + _cmsTagLinkedList *newEntry = ( _cmsTagLinkedList *) _cmsSubAllocDup(ctx ->MemPool, entry, sizeof(_cmsTagLinkedList)); - SupportedTags[DEFAULT_TAG_COUNT-1].Next = NULL; - return TRUE; + if (newEntry == NULL) + return; + + // We want to keep the linked list order, so this is a little bit tricky + newEntry -> Next = NULL; + if (Anterior) + Anterior -> Next = newEntry; + + Anterior = newEntry; + + if (newHead.Tag == NULL) + newHead.Tag = newEntry; + } + + ctx ->chunks[TagPlugin] = _cmsSubAllocDup(ctx->MemPool, &newHead, sizeof(_cmsTagPluginChunkType)); +} + +void _cmsAllocTagPluginChunk(struct _cmsContext_struct* ctx, + const struct _cmsContext_struct* src) +{ + if (src != NULL) { + + DupTagList(ctx, src); + } + else { + static _cmsTagPluginChunkType TagPluginChunk = { NULL }; + ctx ->chunks[TagPlugin] = _cmsSubAllocDup(ctx ->MemPool, &TagPluginChunk, sizeof(_cmsTagPluginChunkType)); } - pt = Anterior = SupportedTags; - while (pt != NULL) { +} - if (Plugin->Signature == pt -> Signature) { - pt ->Descriptor = Plugin ->Descriptor; // Replace old behaviour - return TRUE; - } +cmsBool _cmsRegisterTagPlugin(cmsContext id, cmsPluginBase* Data) +{ + cmsPluginTag* Plugin = (cmsPluginTag*) Data; + _cmsTagLinkedList *pt; + _cmsTagPluginChunkType* TagPluginChunk = ( _cmsTagPluginChunkType*) _cmsContextGetClientChunk(id, TagPlugin); + + if (Data == NULL) { - Anterior = pt; - pt = pt ->Next; + TagPluginChunk->Tag = NULL; + return TRUE; } pt = (_cmsTagLinkedList*) _cmsPluginMalloc(id, sizeof(_cmsTagLinkedList)); @@ -5416,17 +5535,25 @@ pt ->Signature = Plugin ->Signature; pt ->Descriptor = Plugin ->Descriptor; - pt ->Next = NULL; - - if (Anterior != NULL) Anterior -> Next = pt; + pt ->Next = TagPluginChunk ->Tag; + TagPluginChunk ->Tag = pt; + return TRUE; } // Return a descriptor for a given tag or NULL -cmsTagDescriptor* _cmsGetTagDescriptor(cmsTagSignature sig) +cmsTagDescriptor* _cmsGetTagDescriptor(cmsContext ContextID, cmsTagSignature sig) { _cmsTagLinkedList* pt; + _cmsTagPluginChunkType* TagPluginChunk = ( _cmsTagPluginChunkType*) _cmsContextGetClientChunk(ContextID, TagPlugin); + + for (pt = TagPluginChunk->Tag; + pt != NULL; + pt = pt ->Next) { + + if (sig == pt -> Signature) return &pt ->Descriptor; + } for (pt = SupportedTags; pt != NULL; diff -Nru lcms2-2.5/src/cmsvirt.c lcms2-2.6/src/cmsvirt.c --- lcms2-2.5/src/cmsvirt.c 2013-06-27 16:01:28.000000000 +0000 +++ lcms2-2.6/src/cmsvirt.c 2014-03-17 16:09:30.000000000 +0000 @@ -1,7 +1,7 @@ //--------------------------------------------------------------------------------- // // Little Color Management System -// Copyright (c) 1998-2011 Marti Maria Saguer +// Copyright (c) 1998-2014 Marti Maria Saguer // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the "Software"), @@ -990,7 +990,7 @@ static const cmsAllowedLUT AllowedLUTTypes[] = { - { FALSE, 0, cmsSigLut16Type, 4, { cmsSigMatrixElemType, cmsSigCurveSetElemType, cmsSigCLutElemType, cmsSigCurveSetElemType}}, + { FALSE, 0, cmsSigLut16Type, 4, { cmsSigMatrixElemType, cmsSigCurveSetElemType, cmsSigCLutElemType, cmsSigCurveSetElemType}}, { FALSE, 0, cmsSigLut16Type, 3, { cmsSigCurveSetElemType, cmsSigCLutElemType, cmsSigCurveSetElemType}}, { FALSE, 0, cmsSigLut16Type, 2, { cmsSigCurveSetElemType, cmsSigCLutElemType}}, { TRUE , 0, cmsSigLutAtoBType, 1, { cmsSigCurveSetElemType }}, @@ -1121,7 +1121,7 @@ if (AllowedLUT == NULL) { // Try to optimize - _cmsOptimizePipeline(&LUT, xform ->RenderingIntent, &FrmIn, &FrmOut, &dwFlags); + _cmsOptimizePipeline(ContextID, &LUT, xform ->RenderingIntent, &FrmIn, &FrmOut, &dwFlags); AllowedLUT = FindCombination(LUT, Version >= 4.0, DestinationTag); } @@ -1130,7 +1130,7 @@ if (AllowedLUT == NULL) { dwFlags |= cmsFLAGS_FORCE_CLUT; - _cmsOptimizePipeline(&LUT, xform ->RenderingIntent, &FrmIn, &FrmOut, &dwFlags); + _cmsOptimizePipeline(ContextID, &LUT, xform ->RenderingIntent, &FrmIn, &FrmOut, &dwFlags); // Put identity curves if needed if (cmsPipelineGetPtrToFirstStage(LUT) ->Type != cmsSigCurveSetElemType) diff -Nru lcms2-2.5/src/cmswtpnt.c lcms2-2.6/src/cmswtpnt.c --- lcms2-2.5/src/cmswtpnt.c 2013-06-27 16:01:28.000000000 +0000 +++ lcms2-2.6/src/cmswtpnt.c 2014-03-17 16:09:30.000000000 +0000 @@ -1,7 +1,7 @@ //--------------------------------------------------------------------------------- // // Little Color Management System -// Copyright (c) 1998-2012 Marti Maria Saguer +// Copyright (c) 1998-2014 Marti Maria Saguer // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the "Software"), diff -Nru lcms2-2.5/src/cmsxform.c lcms2-2.6/src/cmsxform.c --- lcms2-2.5/src/cmsxform.c 2013-06-27 16:01:28.000000000 +0000 +++ lcms2-2.6/src/cmsxform.c 2014-03-17 16:09:30.000000000 +0000 @@ -1,7 +1,7 @@ //--------------------------------------------------------------------------------- // // Little Color Management System -// Copyright (c) 1998-2011 Marti Maria Saguer +// Copyright (c) 1998-2014 Marti Maria Saguer // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the "Software"), @@ -29,44 +29,120 @@ // Transformations stuff // ----------------------------------------------------------------------- -// Alarm codes for 16-bit transformations, because the fixed range of containers there are -// no values left to mark out of gamut. volatile is C99 per 6.2.5 -static volatile cmsUInt16Number Alarm[cmsMAXCHANNELS] = { 0x7F00, 0x7F00, 0x7F00, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; -static volatile cmsFloat64Number GlobalAdaptationState = 1; +#define DEFAULT_OBSERVER_ADAPTATION_STATE 1.0 + +// The Context0 observer adaptation state. +_cmsAdaptationStateChunkType _cmsAdaptationStateChunk = { DEFAULT_OBSERVER_ADAPTATION_STATE }; + +// Init and duplicate observer adaptation state +void _cmsAllocAdaptationStateChunk(struct _cmsContext_struct* ctx, + const struct _cmsContext_struct* src) +{ + static _cmsAdaptationStateChunkType AdaptationStateChunk = { DEFAULT_OBSERVER_ADAPTATION_STATE }; + void* from; + + if (src != NULL) { + from = src ->chunks[AdaptationStateContext]; + } + else { + from = &AdaptationStateChunk; + } + + ctx ->chunks[AdaptationStateContext] = _cmsSubAllocDup(ctx ->MemPool, from, sizeof(_cmsAdaptationStateChunkType)); +} + + +// Sets adaptation state for absolute colorimetric intent in the given context. Adaptation state applies on all +// but cmsCreateExtendedTransformTHR(). Little CMS can handle incomplete adaptation states. +cmsFloat64Number CMSEXPORT cmsSetAdaptationStateTHR(cmsContext ContextID, cmsFloat64Number d) +{ + cmsFloat64Number prev; + _cmsAdaptationStateChunkType* ptr = (_cmsAdaptationStateChunkType*) _cmsContextGetClientChunk(ContextID, AdaptationStateContext); + + // Get previous value for return + prev = ptr ->AdaptationState; + + // Set the value if d is positive or zero + if (d >= 0.0) { + + ptr ->AdaptationState = d; + } + + // Always return previous value + return prev; +} + // The adaptation state may be defaulted by this function. If you don't like it, use the extended transform routine cmsFloat64Number CMSEXPORT cmsSetAdaptationState(cmsFloat64Number d) -{ - cmsFloat64Number OldVal = GlobalAdaptationState; +{ + return cmsSetAdaptationStateTHR(NULL, d); +} + +// ----------------------------------------------------------------------- - if (d >= 0) - GlobalAdaptationState = d; +// Alarm codes for 16-bit transformations, because the fixed range of containers there are +// no values left to mark out of gamut. + +#define DEFAULT_ALARM_CODES_VALUE {0x7F00, 0x7F00, 0x7F00, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} + +_cmsAlarmCodesChunkType _cmsAlarmCodesChunk = { DEFAULT_ALARM_CODES_VALUE }; - return OldVal; +// Sets the codes used to mark out-out-gamut on Proofing transforms for a given context. Values are meant to be +// encoded in 16 bits. +void CMSEXPORT cmsSetAlarmCodesTHR(cmsContext ContextID, const cmsUInt16Number AlarmCodesP[cmsMAXCHANNELS]) +{ + _cmsAlarmCodesChunkType* ContextAlarmCodes = (_cmsAlarmCodesChunkType*) _cmsContextGetClientChunk(ContextID, AlarmCodesContext); + + _cmsAssert(ContextAlarmCodes != NULL); // Can't happen + + memcpy(ContextAlarmCodes->AlarmCodes, AlarmCodesP, sizeof(ContextAlarmCodes->AlarmCodes)); } -// Alarm codes are always global -void CMSEXPORT cmsSetAlarmCodes(cmsUInt16Number NewAlarm[cmsMAXCHANNELS]) +// Gets the current codes used to mark out-out-gamut on Proofing transforms for the given context. +// Values are meant to be encoded in 16 bits. +void CMSEXPORT cmsGetAlarmCodesTHR(cmsContext ContextID, cmsUInt16Number AlarmCodesP[cmsMAXCHANNELS]) { - int i; + _cmsAlarmCodesChunkType* ContextAlarmCodes = (_cmsAlarmCodesChunkType*) _cmsContextGetClientChunk(ContextID, AlarmCodesContext); - _cmsAssert(NewAlarm != NULL); + _cmsAssert(ContextAlarmCodes != NULL); // Can't happen - for (i=0; i < cmsMAXCHANNELS; i++) - Alarm[i] = NewAlarm[i]; + memcpy(AlarmCodesP, ContextAlarmCodes->AlarmCodes, sizeof(ContextAlarmCodes->AlarmCodes)); } -// You can get the codes cas well -void CMSEXPORT cmsGetAlarmCodes(cmsUInt16Number OldAlarm[cmsMAXCHANNELS]) +void CMSEXPORT cmsSetAlarmCodes(const cmsUInt16Number NewAlarm[cmsMAXCHANNELS]) { - int i; + _cmsAssert(NewAlarm != NULL); + + cmsSetAlarmCodesTHR(NULL, NewAlarm); +} +void CMSEXPORT cmsGetAlarmCodes(cmsUInt16Number OldAlarm[cmsMAXCHANNELS]) +{ _cmsAssert(OldAlarm != NULL); + cmsGetAlarmCodesTHR(NULL, OldAlarm); +} + - for (i=0; i < cmsMAXCHANNELS; i++) - OldAlarm[i] = Alarm[i]; +// Init and duplicate alarm codes +void _cmsAllocAlarmCodesChunk(struct _cmsContext_struct* ctx, + const struct _cmsContext_struct* src) +{ + static _cmsAlarmCodesChunkType AlarmCodesChunk = { DEFAULT_ALARM_CODES_VALUE }; + void* from; + + if (src != NULL) { + from = src ->chunks[AlarmCodesContext]; + } + else { + from = &AlarmCodesChunk; + } + + ctx ->chunks[AlarmCodesContext] = _cmsSubAllocDup(ctx ->MemPool, from, sizeof(_cmsAlarmCodesChunkType)); } +// ----------------------------------------------------------------------- + // Get rid of transform resources void CMSEXPORT cmsDeleteTransform(cmsHTRANSFORM hTransform) { @@ -173,6 +249,30 @@ } } + +static +void NullFloatXFORM(_cmsTRANSFORM* p, + const void* in, + void* out, + cmsUInt32Number Size, + cmsUInt32Number Stride) +{ + cmsUInt8Number* accum; + cmsUInt8Number* output; + cmsFloat32Number fIn[cmsMAXCHANNELS]; + cmsUInt32Number i, n; + + accum = (cmsUInt8Number*) in; + output = (cmsUInt8Number*) out; + n = Size; + + for (i=0; i < n; i++) { + + accum = p -> FromInputFloat(p, fIn, accum, Stride); + output = p -> ToOutputFloat(p, fIn, output, Stride); + } +} + // 16 bit precision ----------------------------------------------------------------------------------------------------------- // Null transformation, only applies formatters. No caché @@ -223,7 +323,7 @@ } -// Auxiliar: Handle precalculated gamut check +// Auxiliar: Handle precalculated gamut check. The retrieval of context may be alittle bit slow, but this function is not critical. static void TransformOnePixelWithGamutCheck(_cmsTRANSFORM* p, const cmsUInt16Number wIn[], @@ -235,9 +335,12 @@ if (wOutOfGamut >= 1) { cmsUInt16Number i; + _cmsAlarmCodesChunkType* ContextAlarmCodes = (_cmsAlarmCodesChunkType*) _cmsContextGetClientChunk(p->ContextID, AlarmCodesContext); - for (i=0; i < p ->Lut->OutputChannels; i++) - wOut[i] = Alarm[i]; + for (i=0; i < p ->Lut->OutputChannels; i++) { + + wOut[i] = ContextAlarmCodes ->AlarmCodes[i]; + } } else p ->Lut ->Eval16Fn(wIn, wOut, p -> Lut->Data); @@ -364,34 +467,86 @@ } _cmsTransformCollection; // The linked list head -static _cmsTransformCollection* TransformCollection = NULL; +_cmsTransformPluginChunkType _cmsTransformPluginChunk = { NULL }; + + +// Duplicates the zone of memory used by the plug-in in the new context +static +void DupPluginTransformList(struct _cmsContext_struct* ctx, + const struct _cmsContext_struct* src) +{ + _cmsTransformPluginChunkType newHead = { NULL }; + _cmsTransformCollection* entry; + _cmsTransformCollection* Anterior = NULL; + _cmsTransformPluginChunkType* head = (_cmsTransformPluginChunkType*) src->chunks[TransformPlugin]; + + // Walk the list copying all nodes + for (entry = head->TransformCollection; + entry != NULL; + entry = entry ->Next) { + + _cmsTransformCollection *newEntry = ( _cmsTransformCollection *) _cmsSubAllocDup(ctx ->MemPool, entry, sizeof(_cmsTransformCollection)); + + if (newEntry == NULL) + return; + + // We want to keep the linked list order, so this is a little bit tricky + newEntry -> Next = NULL; + if (Anterior) + Anterior -> Next = newEntry; + + Anterior = newEntry; + + if (newHead.TransformCollection == NULL) + newHead.TransformCollection = newEntry; + } + + ctx ->chunks[TransformPlugin] = _cmsSubAllocDup(ctx->MemPool, &newHead, sizeof(_cmsTransformPluginChunkType)); +} + +void _cmsAllocTransformPluginChunk(struct _cmsContext_struct* ctx, + const struct _cmsContext_struct* src) +{ + if (src != NULL) { + + // Copy all linked list + DupPluginTransformList(ctx, src); + } + else { + static _cmsTransformPluginChunkType TransformPluginChunkType = { NULL }; + ctx ->chunks[TransformPlugin] = _cmsSubAllocDup(ctx ->MemPool, &TransformPluginChunkType, sizeof(_cmsTransformPluginChunkType)); + } +} + + // Register new ways to transform -cmsBool _cmsRegisterTransformPlugin(cmsContext id, cmsPluginBase* Data) +cmsBool _cmsRegisterTransformPlugin(cmsContext ContextID, cmsPluginBase* Data) { cmsPluginTransform* Plugin = (cmsPluginTransform*) Data; _cmsTransformCollection* fl; + _cmsTransformPluginChunkType* ctx = ( _cmsTransformPluginChunkType*) _cmsContextGetClientChunk(ContextID,TransformPlugin); - if (Data == NULL) { + if (Data == NULL) { // Free the chain. Memory is safely freed at exit - TransformCollection = NULL; + ctx->TransformCollection = NULL; return TRUE; } // Factory callback is required - if (Plugin ->Factory == NULL) return FALSE; + if (Plugin ->Factory == NULL) return FALSE; - fl = (_cmsTransformCollection*) _cmsPluginMalloc(id, sizeof(_cmsTransformCollection)); + fl = (_cmsTransformCollection*) _cmsPluginMalloc(ContextID, sizeof(_cmsTransformCollection)); if (fl == NULL) return FALSE; - // Copy the parameters + // Copy the parameters fl ->Factory = Plugin ->Factory; // Keep linked list - fl ->Next = TransformCollection; - TransformCollection = fl; + fl ->Next = ctx->TransformCollection; + ctx->TransformCollection = fl; // All is ok return TRUE; @@ -434,6 +589,7 @@ _cmsTRANSFORM* AllocEmptyTransform(cmsContext ContextID, cmsPipeline* lut, cmsUInt32Number Intent, cmsUInt32Number* InputFormat, cmsUInt32Number* OutputFormat, cmsUInt32Number* dwFlags) { + _cmsTransformPluginChunkType* ctx = ( _cmsTransformPluginChunkType*) _cmsContextGetClientChunk(ContextID, TransformPlugin); _cmsTransformCollection* Plugin; // Allocate needed memory @@ -444,7 +600,7 @@ p ->Lut = lut; // Let's see if any plug-in want to do the transform by itself - for (Plugin = TransformCollection; + for (Plugin = ctx ->TransformCollection; Plugin != NULL; Plugin = Plugin ->Next) { @@ -464,10 +620,10 @@ // 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(*InputFormat, cmsFormatterInput, CMS_PACK_FLAGS_16BITS).Fmt16; - p ->ToOutput = _cmsGetFormatter(*OutputFormat, cmsFormatterOutput, CMS_PACK_FLAGS_16BITS).Fmt16; - p ->FromInputFloat = _cmsGetFormatter(*InputFormat, cmsFormatterInput, CMS_PACK_FLAGS_FLOAT).FmtFloat; - p ->ToOutputFloat = _cmsGetFormatter(*OutputFormat, cmsFormatterOutput, CMS_PACK_FLAGS_FLOAT).FmtFloat; + 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; return p; } @@ -475,14 +631,14 @@ // Not suitable for the transform plug-in, let's check the pipeline plug-in if (p ->Lut != NULL) - _cmsOptimizePipeline(&p->Lut, Intent, InputFormat, OutputFormat, dwFlags); + _cmsOptimizePipeline(ContextID, &p->Lut, Intent, InputFormat, OutputFormat, dwFlags); // Check whatever this is a true floating point transform if (_cmsFormatterIsFloat(*InputFormat) && _cmsFormatterIsFloat(*OutputFormat)) { // Get formatter function always return a valid union, but the contents of this union may be NULL. - p ->FromInputFloat = _cmsGetFormatter(*InputFormat, cmsFormatterInput, CMS_PACK_FLAGS_FLOAT).FmtFloat; - p ->ToOutputFloat = _cmsGetFormatter(*OutputFormat, cmsFormatterOutput, CMS_PACK_FLAGS_FLOAT).FmtFloat; + p ->FromInputFloat = _cmsGetFormatter(ContextID, *InputFormat, cmsFormatterInput, CMS_PACK_FLAGS_FLOAT).FmtFloat; + p ->ToOutputFloat = _cmsGetFormatter(ContextID, *OutputFormat, cmsFormatterOutput, CMS_PACK_FLAGS_FLOAT).FmtFloat; *dwFlags |= cmsFLAGS_CAN_CHANGE_FORMATTER; if (p ->FromInputFloat == NULL || p ->ToOutputFloat == NULL) { @@ -492,8 +648,15 @@ return NULL; } - // Float transforms don't use caché, always are non-NULL - p ->xform = FloatXFORM; + if (*dwFlags & cmsFLAGS_NULLTRANSFORM) { + + p ->xform = NullFloatXFORM; + } + else { + // Float transforms don't use caché, always are non-NULL + p ->xform = FloatXFORM; + } + } else { @@ -505,8 +668,8 @@ int BytesPerPixelInput; - p ->FromInput = _cmsGetFormatter(*InputFormat, cmsFormatterInput, CMS_PACK_FLAGS_16BITS).Fmt16; - p ->ToOutput = _cmsGetFormatter(*OutputFormat, cmsFormatterOutput, CMS_PACK_FLAGS_16BITS).Fmt16; + p ->FromInput = _cmsGetFormatter(ContextID, *InputFormat, cmsFormatterInput, CMS_PACK_FLAGS_16BITS).Fmt16; + p ->ToOutput = _cmsGetFormatter(ContextID, *OutputFormat, cmsFormatterOutput, CMS_PACK_FLAGS_16BITS).Fmt16; if (p ->FromInput == NULL || p ->ToOutput == NULL) { @@ -698,6 +861,7 @@ // Check channel count if ((cmsChannelsOf(EntryColorSpace) != cmsPipelineInputChannels(Lut)) || (cmsChannelsOf(ExitColorSpace) != cmsPipelineOutputChannels(Lut))) { + cmsPipelineFree(Lut); cmsSignalError(ContextID, cmsERROR_NOT_SUITABLE, "Channel count doesn't match. Profile is corrupted"); return NULL; } @@ -800,7 +964,7 @@ for (i=0; i < nProfiles; i++) { BPC[i] = dwFlags & cmsFLAGS_BLACKPOINTCOMPENSATION ? TRUE : FALSE; Intents[i] = Intent; - AdaptationStates[i] = GlobalAdaptationState; + AdaptationStates[i] = cmsSetAdaptationStateTHR(ContextID, -1); } @@ -880,7 +1044,7 @@ Intents[0] = nIntent; Intents[1] = nIntent; Intents[2] = INTENT_RELATIVE_COLORIMETRIC; Intents[3] = ProofingIntent; BPC[0] = DoBPC; BPC[1] = DoBPC; BPC[2] = 0; BPC[3] = 0; - Adaptation[0] = Adaptation[1] = Adaptation[2] = Adaptation[3] = GlobalAdaptationState; + Adaptation[0] = Adaptation[1] = Adaptation[2] = Adaptation[3] = cmsSetAdaptationStateTHR(ContextID, -1); if (!(dwFlags & (cmsFLAGS_SOFTPROOFING|cmsFLAGS_GAMUTCHECK))) return cmsCreateTransformTHR(ContextID, InputProfile, InputFormat, OutputProfile, OutputFormat, nIntent, dwFlags); @@ -955,8 +1119,8 @@ return FALSE; } - FromInput = _cmsGetFormatter(InputFormat, cmsFormatterInput, CMS_PACK_FLAGS_16BITS).Fmt16; - ToOutput = _cmsGetFormatter(OutputFormat, cmsFormatterOutput, CMS_PACK_FLAGS_16BITS).Fmt16; + FromInput = _cmsGetFormatter(xform->ContextID, InputFormat, cmsFormatterInput, CMS_PACK_FLAGS_16BITS).Fmt16; + ToOutput = _cmsGetFormatter(xform->ContextID, OutputFormat, cmsFormatterOutput, CMS_PACK_FLAGS_16BITS).Fmt16; if (FromInput == NULL || ToOutput == NULL) { diff -Nru lcms2-2.5/src/lcms2.def lcms2-2.6/src/lcms2.def --- lcms2-2.5/src/lcms2.def 2013-06-27 16:01:28.000000000 +0000 +++ lcms2-2.6/src/lcms2.def 2014-03-17 16:09:30.000000000 +0000 @@ -1,325 +1,341 @@ -LIBRARY LCMS2.DLL - -EXPORTS - -_cms15Fixed16toDouble = _cms15Fixed16toDouble -_cms8Fixed8toDouble = _cms8Fixed8toDouble -cmsAdaptToIlluminant = cmsAdaptToIlluminant -_cmsAdjustEndianess16 = _cmsAdjustEndianess16 -_cmsAdjustEndianess32 = _cmsAdjustEndianess32 -_cmsAdjustEndianess64 = _cmsAdjustEndianess64 -cmsAllocNamedColorList = cmsAllocNamedColorList -cmsAllocProfileSequenceDescription = cmsAllocProfileSequenceDescription -cmsAppendNamedColor = cmsAppendNamedColor -cmsBFDdeltaE = cmsBFDdeltaE -cmsBuildGamma = cmsBuildGamma -cmsBuildParametricToneCurve = cmsBuildParametricToneCurve -cmsBuildSegmentedToneCurve = cmsBuildSegmentedToneCurve -cmsBuildTabulatedToneCurve16 = cmsBuildTabulatedToneCurve16 -cmsBuildTabulatedToneCurveFloat = cmsBuildTabulatedToneCurveFloat -_cmsCalloc = _cmsCalloc -cmsChannelsOf = cmsChannelsOf -cmsCIE2000DeltaE = cmsCIE2000DeltaE -cmsCIE94DeltaE = cmsCIE94DeltaE -cmsCIECAM02Done = cmsCIECAM02Done -cmsCIECAM02Forward = cmsCIECAM02Forward -cmsCIECAM02Init = cmsCIECAM02Init -cmsCIECAM02Reverse = cmsCIECAM02Reverse -cmsCloseIOhandler = cmsCloseIOhandler -cmsCloseProfile = cmsCloseProfile -cmsCMCdeltaE = cmsCMCdeltaE -cmsCreate_sRGBProfile = cmsCreate_sRGBProfile -cmsCreate_sRGBProfileTHR = cmsCreate_sRGBProfileTHR -cmsCreateBCHSWabstractProfile = cmsCreateBCHSWabstractProfile -cmsCreateBCHSWabstractProfileTHR = cmsCreateBCHSWabstractProfileTHR -cmsCreateExtendedTransform = cmsCreateExtendedTransform -cmsCreateGrayProfile = cmsCreateGrayProfile -cmsCreateGrayProfileTHR = cmsCreateGrayProfileTHR -cmsCreateInkLimitingDeviceLink = cmsCreateInkLimitingDeviceLink -cmsCreateInkLimitingDeviceLinkTHR = cmsCreateInkLimitingDeviceLinkTHR -cmsCreateLab2Profile = cmsCreateLab2Profile -cmsCreateLab2ProfileTHR = cmsCreateLab2ProfileTHR -cmsCreateLab4Profile = cmsCreateLab4Profile -cmsCreateLab4ProfileTHR = cmsCreateLab4ProfileTHR -cmsCreateLinearizationDeviceLink = cmsCreateLinearizationDeviceLink -cmsCreateLinearizationDeviceLinkTHR = cmsCreateLinearizationDeviceLinkTHR -cmsCreateMultiprofileTransform = cmsCreateMultiprofileTransform -cmsCreateMultiprofileTransformTHR = cmsCreateMultiprofileTransformTHR -cmsCreateNULLProfile = cmsCreateNULLProfile -cmsCreateNULLProfileTHR = cmsCreateNULLProfileTHR -cmsCreateProfilePlaceholder = cmsCreateProfilePlaceholder -cmsCreateProofingTransform = cmsCreateProofingTransform -cmsCreateProofingTransformTHR = cmsCreateProofingTransformTHR -cmsCreateRGBProfile = cmsCreateRGBProfile -cmsCreateRGBProfileTHR = cmsCreateRGBProfileTHR -cmsCreateTransform = cmsCreateTransform -cmsCreateTransformTHR = cmsCreateTransformTHR -cmsCreateXYZProfile = cmsCreateXYZProfile -cmsCreateXYZProfileTHR = cmsCreateXYZProfileTHR -cmsD50_xyY = cmsD50_xyY -cmsD50_XYZ = cmsD50_XYZ -_cmsDecodeDateTimeNumber = _cmsDecodeDateTimeNumber -_cmsDefaultICCintents = _cmsDefaultICCintents -cmsDeleteTransform = cmsDeleteTransform -cmsDeltaE = cmsDeltaE -cmsDetectBlackPoint = cmsDetectBlackPoint -cmsDetectDestinationBlackPoint = cmsDetectDestinationBlackPoint -cmsDetectTAC = cmsDetectTAC -cmsDesaturateLab = cmsDesaturateLab -cmsDoTransform = cmsDoTransform -cmsDoTransformStride = cmsDoTransformStride -_cmsDoubleTo15Fixed16 = _cmsDoubleTo15Fixed16 -_cmsDoubleTo8Fixed8 = _cmsDoubleTo8Fixed8 -_cmsDupMem = _cmsDupMem -cmsDupNamedColorList = cmsDupNamedColorList -cmsDupProfileSequenceDescription = cmsDupProfileSequenceDescription -cmsDupToneCurve = cmsDupToneCurve -_cmsEncodeDateTimeNumber = _cmsEncodeDateTimeNumber -cmsEstimateGamma = cmsEstimateGamma -cmsGetToneCurveEstimatedTableEntries = cmsGetToneCurveEstimatedTableEntries -cmsGetToneCurveEstimatedTable = cmsGetToneCurveEstimatedTable -cmsEvalToneCurve16 = cmsEvalToneCurve16 -cmsEvalToneCurveFloat = cmsEvalToneCurveFloat -cmsfilelength = cmsfilelength -cmsFloat2LabEncoded = cmsFloat2LabEncoded -cmsFloat2LabEncodedV2 = cmsFloat2LabEncodedV2 -cmsFloat2XYZEncoded = cmsFloat2XYZEncoded -cmsFormatterForColorspaceOfProfile = cmsFormatterForColorspaceOfProfile -cmsFormatterForPCSOfProfile = cmsFormatterForPCSOfProfile -_cmsFree = _cmsFree -cmsFreeNamedColorList = cmsFreeNamedColorList -cmsFreeProfileSequenceDescription = cmsFreeProfileSequenceDescription -cmsFreeToneCurve = cmsFreeToneCurve -cmsFreeToneCurveTriple = cmsFreeToneCurveTriple -cmsGBDAlloc = cmsGBDAlloc -cmsGBDFree = cmsGBDFree -cmsGDBAddPoint = cmsGDBAddPoint -cmsGDBCheckPoint = cmsGDBCheckPoint -cmsGDBCompute = cmsGDBCompute -cmsGetAlarmCodes = cmsGetAlarmCodes -cmsGetColorSpace = cmsGetColorSpace -cmsGetDeviceClass = cmsGetDeviceClass -cmsGetEncodedICCversion = cmsGetEncodedICCversion -cmsGetHeaderAttributes = cmsGetHeaderAttributes -cmsGetHeaderCreationDateTime = cmsGetHeaderCreationDateTime -cmsGetHeaderFlags = cmsGetHeaderFlags -cmsGetHeaderManufacturer = cmsGetHeaderManufacturer -cmsGetHeaderModel = cmsGetHeaderModel -cmsGetHeaderProfileID = cmsGetHeaderProfileID -cmsGetHeaderRenderingIntent = cmsGetHeaderRenderingIntent -cmsGetNamedColorList = cmsGetNamedColorList -cmsGetPCS = cmsGetPCS -cmsGetPostScriptColorResource = cmsGetPostScriptColorResource -cmsGetPostScriptCRD = cmsGetPostScriptCRD -cmsGetPostScriptCSA = cmsGetPostScriptCSA -cmsGetProfileInfo = cmsGetProfileInfo -cmsGetProfileInfoASCII = cmsGetProfileInfoASCII -cmsGetProfileContextID = cmsGetProfileContextID -cmsGetProfileVersion = cmsGetProfileVersion -cmsGetSupportedIntents = cmsGetSupportedIntents -cmsGetTagCount = cmsGetTagCount -cmsGetTagSignature = cmsGetTagSignature -cmsGetTransformContextID = cmsGetTransformContextID -_cmsICCcolorSpace = _cmsICCcolorSpace -_cmsIOPrintf = _cmsIOPrintf -cmsIsCLUT = cmsIsCLUT -cmsIsIntentSupported = cmsIsIntentSupported -cmsIsMatrixShaper = cmsIsMatrixShaper -cmsIsTag = cmsIsTag -cmsIsToneCurveDescending = cmsIsToneCurveDescending -cmsIsToneCurveLinear = cmsIsToneCurveLinear -cmsIsToneCurveMonotonic = cmsIsToneCurveMonotonic -cmsIsToneCurveMultisegment = cmsIsToneCurveMultisegment -cmsGetToneCurveParametricType = cmsGetToneCurveParametricType -cmsIT8Alloc = cmsIT8Alloc -cmsIT8DefineDblFormat = cmsIT8DefineDblFormat -cmsIT8EnumDataFormat = cmsIT8EnumDataFormat -cmsIT8EnumProperties = cmsIT8EnumProperties -cmsIT8EnumPropertyMulti = cmsIT8EnumPropertyMulti -cmsIT8Free = cmsIT8Free -cmsIT8GetData = cmsIT8GetData -cmsIT8GetDataDbl = cmsIT8GetDataDbl -cmsIT8FindDataFormat = cmsIT8FindDataFormat -cmsIT8GetDataRowCol = cmsIT8GetDataRowCol -cmsIT8GetDataRowColDbl = cmsIT8GetDataRowColDbl -cmsIT8GetPatchName = cmsIT8GetPatchName -cmsIT8GetPatchByName = cmsIT8GetPatchByName -cmsIT8GetProperty = cmsIT8GetProperty -cmsIT8GetPropertyDbl = cmsIT8GetPropertyDbl -cmsIT8GetPropertyMulti = cmsIT8GetPropertyMulti -cmsIT8GetSheetType = cmsIT8GetSheetType -cmsIT8LoadFromFile = cmsIT8LoadFromFile -cmsIT8LoadFromMem = cmsIT8LoadFromMem -cmsIT8SaveToFile = cmsIT8SaveToFile -cmsIT8SaveToMem = cmsIT8SaveToMem -cmsIT8SetComment = cmsIT8SetComment -cmsIT8SetData = cmsIT8SetData -cmsIT8SetDataDbl = cmsIT8SetDataDbl -cmsIT8SetDataFormat = cmsIT8SetDataFormat -cmsIT8SetDataRowCol = cmsIT8SetDataRowCol -cmsIT8SetDataRowColDbl = cmsIT8SetDataRowColDbl -cmsIT8SetPropertyDbl = cmsIT8SetPropertyDbl -cmsIT8SetPropertyHex = cmsIT8SetPropertyHex -cmsIT8SetPropertyStr = cmsIT8SetPropertyStr -cmsIT8SetPropertyMulti = cmsIT8SetPropertyMulti -cmsIT8SetPropertyUncooked = cmsIT8SetPropertyUncooked -cmsIT8SetSheetType = cmsIT8SetSheetType -cmsIT8SetTable = cmsIT8SetTable -cmsIT8SetTableByLabel = cmsIT8SetTableByLabel -cmsIT8SetIndexColumn = cmsIT8SetIndexColumn -cmsIT8TableCount = cmsIT8TableCount -cmsJoinToneCurve = cmsJoinToneCurve -cmsLab2LCh = cmsLab2LCh -cmsLab2XYZ = cmsLab2XYZ -cmsLabEncoded2Float = cmsLabEncoded2Float -cmsLabEncoded2FloatV2 = cmsLabEncoded2FloatV2 -cmsLCh2Lab = cmsLCh2Lab -_cmsLCMScolorSpace = _cmsLCMScolorSpace -cmsLinkTag = cmsLinkTag -cmsTagLinkedTo = cmsTagLinkedTo -cmsPipelineAlloc = cmsPipelineAlloc -cmsPipelineCat = cmsPipelineCat -cmsPipelineCheckAndRetreiveStages = cmsPipelineCheckAndRetreiveStages -cmsPipelineDup = cmsPipelineDup -cmsPipelineStageCount = cmsPipelineStageCount -cmsPipelineEval16 = cmsPipelineEval16 -cmsPipelineEvalFloat = cmsPipelineEvalFloat -cmsPipelineEvalReverseFloat = cmsPipelineEvalReverseFloat -cmsPipelineFree = cmsPipelineFree -cmsPipelineGetPtrToFirstStage = cmsPipelineGetPtrToFirstStage -cmsPipelineGetPtrToLastStage = cmsPipelineGetPtrToLastStage -cmsPipelineInputChannels = cmsPipelineInputChannels -cmsPipelineInsertStage = cmsPipelineInsertStage -cmsPipelineOutputChannels = cmsPipelineOutputChannels -cmsPipelineSetSaveAs8bitsFlag = cmsPipelineSetSaveAs8bitsFlag -_cmsPipelineSetOptimizationParameters = _cmsPipelineSetOptimizationParameters -cmsPipelineUnlinkStage = cmsPipelineUnlinkStage -_cmsMalloc = _cmsMalloc -_cmsMallocZero = _cmsMallocZero -_cmsMAT3eval = _cmsMAT3eval -_cmsMAT3identity = _cmsMAT3identity -_cmsMAT3inverse = _cmsMAT3inverse -_cmsMAT3isIdentity = _cmsMAT3isIdentity -_cmsMAT3per = _cmsMAT3per -_cmsMAT3solve = _cmsMAT3solve -cmsMD5computeID = cmsMD5computeID -cmsMLUalloc = cmsMLUalloc -cmsMLUdup = cmsMLUdup -cmsMLUfree = cmsMLUfree -cmsMLUgetASCII = cmsMLUgetASCII -cmsMLUgetTranslation = cmsMLUgetTranslation -cmsMLUgetWide = cmsMLUgetWide -cmsMLUsetASCII = cmsMLUsetASCII -cmsMLUsetWide = cmsMLUsetWide -cmsStageAllocCLut16bit = cmsStageAllocCLut16bit -cmsStageAllocCLut16bitGranular = cmsStageAllocCLut16bitGranular -cmsStageAllocCLutFloat = cmsStageAllocCLutFloat -cmsStageAllocCLutFloatGranular = cmsStageAllocCLutFloatGranular -cmsStageAllocToneCurves = cmsStageAllocToneCurves -cmsStageAllocIdentity = cmsStageAllocIdentity -cmsStageAllocMatrix = cmsStageAllocMatrix -_cmsStageAllocPlaceholder = _cmsStageAllocPlaceholder -cmsStageDup = cmsStageDup -cmsStageFree = cmsStageFree -cmsStageNext = cmsStageNext -cmsStageInputChannels = cmsStageInputChannels -cmsStageOutputChannels = cmsStageOutputChannels -cmsStageSampleCLut16bit = cmsStageSampleCLut16bit -cmsStageSampleCLutFloat = cmsStageSampleCLutFloat -cmsStageType = cmsStageType -cmsStageData = cmsStageData -cmsNamedColorCount = cmsNamedColorCount -cmsNamedColorIndex = cmsNamedColorIndex -cmsNamedColorInfo = cmsNamedColorInfo -cmsOpenIOhandlerFromFile = cmsOpenIOhandlerFromFile -cmsOpenIOhandlerFromMem = cmsOpenIOhandlerFromMem -cmsOpenIOhandlerFromNULL = cmsOpenIOhandlerFromNULL -cmsOpenIOhandlerFromStream = cmsOpenIOhandlerFromStream -cmsOpenProfileFromFile = cmsOpenProfileFromFile -cmsOpenProfileFromFileTHR = cmsOpenProfileFromFileTHR -cmsOpenProfileFromIOhandlerTHR = cmsOpenProfileFromIOhandlerTHR -cmsOpenProfileFromMem = cmsOpenProfileFromMem -cmsOpenProfileFromMemTHR = cmsOpenProfileFromMemTHR -cmsOpenProfileFromStream = cmsOpenProfileFromStream -cmsOpenProfileFromStreamTHR = cmsOpenProfileFromStreamTHR -cmsPlugin = cmsPlugin -_cmsRead15Fixed16Number = _cmsRead15Fixed16Number -_cmsReadAlignment = _cmsReadAlignment -_cmsReadFloat32Number = _cmsReadFloat32Number -cmsReadRawTag = cmsReadRawTag -cmsReadTag = cmsReadTag -_cmsReadTypeBase = _cmsReadTypeBase -_cmsReadUInt16Array = _cmsReadUInt16Array -_cmsReadUInt16Number = _cmsReadUInt16Number -_cmsReadUInt32Number = _cmsReadUInt32Number -_cmsReadUInt64Number = _cmsReadUInt64Number -_cmsReadUInt8Number = _cmsReadUInt8Number -_cmsReadXYZNumber = _cmsReadXYZNumber -_cmsRealloc = _cmsRealloc -cmsReverseToneCurve = cmsReverseToneCurve -cmsReverseToneCurveEx = cmsReverseToneCurveEx -cmsSaveProfileToFile = cmsSaveProfileToFile -cmsSaveProfileToIOhandler = cmsSaveProfileToIOhandler -cmsSaveProfileToMem = cmsSaveProfileToMem -cmsSaveProfileToStream = cmsSaveProfileToStream -cmsSetAdaptationState = cmsSetAdaptationState -cmsSetAlarmCodes = cmsSetAlarmCodes -cmsSetColorSpace = cmsSetColorSpace -cmsSetDeviceClass = cmsSetDeviceClass -cmsSetEncodedICCversion = cmsSetEncodedICCversion -cmsSetHeaderAttributes = cmsSetHeaderAttributes -cmsSetHeaderFlags = cmsSetHeaderFlags -cmsSetHeaderManufacturer = cmsSetHeaderManufacturer -cmsSetHeaderModel = cmsSetHeaderModel -cmsSetHeaderProfileID = cmsSetHeaderProfileID -cmsSetHeaderRenderingIntent = cmsSetHeaderRenderingIntent -cmsSetLogErrorHandler = cmsSetLogErrorHandler -cmsSetPCS = cmsSetPCS -cmsSetProfileVersion = cmsSetProfileVersion -cmsSignalError = cmsSignalError -cmsSmoothToneCurve = cmsSmoothToneCurve -cmsstrcasecmp = cmsstrcasecmp -cmsTempFromWhitePoint = cmsTempFromWhitePoint -cmsTransform2DeviceLink = cmsTransform2DeviceLink -cmsUnregisterPlugins = cmsUnregisterPlugins -_cmsVEC3cross = _cmsVEC3cross -_cmsVEC3distance = _cmsVEC3distance -_cmsVEC3dot = _cmsVEC3dot -_cmsVEC3init = _cmsVEC3init -_cmsVEC3length = _cmsVEC3length -_cmsVEC3minus = _cmsVEC3minus -cmsWhitePointFromTemp = cmsWhitePointFromTemp -_cmsWrite15Fixed16Number = _cmsWrite15Fixed16Number -_cmsWriteAlignment = _cmsWriteAlignment -_cmsWriteFloat32Number = _cmsWriteFloat32Number -cmsWriteRawTag = cmsWriteRawTag -cmsWriteTag = cmsWriteTag -_cmsWriteTypeBase = _cmsWriteTypeBase -_cmsWriteUInt16Array = _cmsWriteUInt16Array -_cmsWriteUInt16Number = _cmsWriteUInt16Number -_cmsWriteUInt32Number = _cmsWriteUInt32Number -_cmsWriteUInt64Number = _cmsWriteUInt64Number -_cmsWriteUInt8Number = _cmsWriteUInt8Number -_cmsWriteXYZNumber = _cmsWriteXYZNumber -cmsxyY2XYZ = cmsxyY2XYZ -cmsXYZ2Lab = cmsXYZ2Lab -cmsXYZ2xyY = cmsXYZ2xyY -cmsXYZEncoded2Float = cmsXYZEncoded2Float -cmsSliceSpace16 = cmsSliceSpace16 -cmsSliceSpaceFloat = cmsSliceSpaceFloat -cmsChangeBuffersFormat = cmsChangeBuffersFormat -cmsDictAlloc = cmsDictAlloc -cmsDictFree = cmsDictFree -cmsDictDup = cmsDictDup -cmsDictAddEntry = cmsDictAddEntry -cmsDictGetEntryList = cmsDictGetEntryList -cmsDictNextEntry = cmsDictNextEntry -_cmsGetTransformUserData = _cmsGetTransformUserData -_cmsSetTransformUserData = _cmsSetTransformUserData -_cmsGetTransformFormatters16 = _cmsGetTransformFormatters16 -_cmsGetTransformFormattersFloat = _cmsGetTransformFormattersFloat -cmsGetHeaderCreator = cmsGetHeaderCreator -cmsPluginTHR = cmsPluginTHR -cmsGetPipelineContextID = cmsGetPipelineContextID -cmsGetTransformInputFormat = cmsGetTransformInputFormat -cmsGetTransformOutputFormat = cmsGetTransformOutputFormat +LIBRARY LCMS2.DLL + +EXPORTS + +_cms15Fixed16toDouble = _cms15Fixed16toDouble +_cms8Fixed8toDouble = _cms8Fixed8toDouble +cmsAdaptToIlluminant = cmsAdaptToIlluminant +_cmsAdjustEndianess16 = _cmsAdjustEndianess16 +_cmsAdjustEndianess32 = _cmsAdjustEndianess32 +_cmsAdjustEndianess64 = _cmsAdjustEndianess64 +cmsAllocNamedColorList = cmsAllocNamedColorList +cmsAllocProfileSequenceDescription = cmsAllocProfileSequenceDescription +cmsAppendNamedColor = cmsAppendNamedColor +cmsBFDdeltaE = cmsBFDdeltaE +cmsBuildGamma = cmsBuildGamma +cmsBuildParametricToneCurve = cmsBuildParametricToneCurve +cmsBuildSegmentedToneCurve = cmsBuildSegmentedToneCurve +cmsBuildTabulatedToneCurve16 = cmsBuildTabulatedToneCurve16 +cmsBuildTabulatedToneCurveFloat = cmsBuildTabulatedToneCurveFloat +_cmsCalloc = _cmsCalloc +cmsChannelsOf = cmsChannelsOf +cmsCIE2000DeltaE = cmsCIE2000DeltaE +cmsCIE94DeltaE = cmsCIE94DeltaE +cmsCIECAM02Done = cmsCIECAM02Done +cmsCIECAM02Forward = cmsCIECAM02Forward +cmsCIECAM02Init = cmsCIECAM02Init +cmsCIECAM02Reverse = cmsCIECAM02Reverse +cmsCloseIOhandler = cmsCloseIOhandler +cmsCloseProfile = cmsCloseProfile +cmsCMCdeltaE = cmsCMCdeltaE +cmsCreate_sRGBProfile = cmsCreate_sRGBProfile +cmsCreate_sRGBProfileTHR = cmsCreate_sRGBProfileTHR +cmsCreateBCHSWabstractProfile = cmsCreateBCHSWabstractProfile +cmsCreateBCHSWabstractProfileTHR = cmsCreateBCHSWabstractProfileTHR +cmsCreateExtendedTransform = cmsCreateExtendedTransform +cmsCreateGrayProfile = cmsCreateGrayProfile +cmsCreateGrayProfileTHR = cmsCreateGrayProfileTHR +cmsCreateInkLimitingDeviceLink = cmsCreateInkLimitingDeviceLink +cmsCreateInkLimitingDeviceLinkTHR = cmsCreateInkLimitingDeviceLinkTHR +cmsCreateLab2Profile = cmsCreateLab2Profile +cmsCreateLab2ProfileTHR = cmsCreateLab2ProfileTHR +cmsCreateLab4Profile = cmsCreateLab4Profile +cmsCreateLab4ProfileTHR = cmsCreateLab4ProfileTHR +cmsCreateLinearizationDeviceLink = cmsCreateLinearizationDeviceLink +cmsCreateLinearizationDeviceLinkTHR = cmsCreateLinearizationDeviceLinkTHR +cmsCreateMultiprofileTransform = cmsCreateMultiprofileTransform +cmsCreateMultiprofileTransformTHR = cmsCreateMultiprofileTransformTHR +cmsCreateNULLProfile = cmsCreateNULLProfile +cmsCreateNULLProfileTHR = cmsCreateNULLProfileTHR +cmsCreateProfilePlaceholder = cmsCreateProfilePlaceholder +cmsCreateProofingTransform = cmsCreateProofingTransform +cmsCreateProofingTransformTHR = cmsCreateProofingTransformTHR +cmsCreateRGBProfile = cmsCreateRGBProfile +cmsCreateRGBProfileTHR = cmsCreateRGBProfileTHR +cmsCreateTransform = cmsCreateTransform +cmsCreateTransformTHR = cmsCreateTransformTHR +cmsCreateXYZProfile = cmsCreateXYZProfile +cmsCreateXYZProfileTHR = cmsCreateXYZProfileTHR +cmsD50_xyY = cmsD50_xyY +cmsD50_XYZ = cmsD50_XYZ +_cmsDecodeDateTimeNumber = _cmsDecodeDateTimeNumber +_cmsDefaultICCintents = _cmsDefaultICCintents +cmsDeleteTransform = cmsDeleteTransform +cmsDeltaE = cmsDeltaE +cmsDetectBlackPoint = cmsDetectBlackPoint +cmsDetectDestinationBlackPoint = cmsDetectDestinationBlackPoint +cmsDetectTAC = cmsDetectTAC +cmsDesaturateLab = cmsDesaturateLab +cmsDoTransform = cmsDoTransform +cmsDoTransformStride = cmsDoTransformStride +_cmsDoubleTo15Fixed16 = _cmsDoubleTo15Fixed16 +_cmsDoubleTo8Fixed8 = _cmsDoubleTo8Fixed8 +_cmsDupMem = _cmsDupMem +cmsDupNamedColorList = cmsDupNamedColorList +cmsDupProfileSequenceDescription = cmsDupProfileSequenceDescription +cmsDupToneCurve = cmsDupToneCurve +_cmsEncodeDateTimeNumber = _cmsEncodeDateTimeNumber +cmsEstimateGamma = cmsEstimateGamma +cmsGetToneCurveEstimatedTableEntries = cmsGetToneCurveEstimatedTableEntries +cmsGetToneCurveEstimatedTable = cmsGetToneCurveEstimatedTable +cmsEvalToneCurve16 = cmsEvalToneCurve16 +cmsEvalToneCurveFloat = cmsEvalToneCurveFloat +cmsfilelength = cmsfilelength +cmsFloat2LabEncoded = cmsFloat2LabEncoded +cmsFloat2LabEncodedV2 = cmsFloat2LabEncodedV2 +cmsFloat2XYZEncoded = cmsFloat2XYZEncoded +cmsFormatterForColorspaceOfProfile = cmsFormatterForColorspaceOfProfile +cmsFormatterForPCSOfProfile = cmsFormatterForPCSOfProfile +_cmsFree = _cmsFree +cmsFreeNamedColorList = cmsFreeNamedColorList +cmsFreeProfileSequenceDescription = cmsFreeProfileSequenceDescription +cmsFreeToneCurve = cmsFreeToneCurve +cmsFreeToneCurveTriple = cmsFreeToneCurveTriple +cmsGBDAlloc = cmsGBDAlloc +cmsGBDFree = cmsGBDFree +cmsGDBAddPoint = cmsGDBAddPoint +cmsGDBCheckPoint = cmsGDBCheckPoint +cmsGDBCompute = cmsGDBCompute +cmsGetAlarmCodes = cmsGetAlarmCodes +cmsGetColorSpace = cmsGetColorSpace +cmsGetDeviceClass = cmsGetDeviceClass +cmsGetEncodedICCversion = cmsGetEncodedICCversion +cmsGetHeaderAttributes = cmsGetHeaderAttributes +cmsGetHeaderCreationDateTime = cmsGetHeaderCreationDateTime +cmsGetHeaderFlags = cmsGetHeaderFlags +cmsGetHeaderManufacturer = cmsGetHeaderManufacturer +cmsGetHeaderModel = cmsGetHeaderModel +cmsGetHeaderProfileID = cmsGetHeaderProfileID +cmsGetHeaderRenderingIntent = cmsGetHeaderRenderingIntent +cmsGetNamedColorList = cmsGetNamedColorList +cmsGetPCS = cmsGetPCS +cmsGetPostScriptColorResource = cmsGetPostScriptColorResource +cmsGetPostScriptCRD = cmsGetPostScriptCRD +cmsGetPostScriptCSA = cmsGetPostScriptCSA +cmsGetProfileInfo = cmsGetProfileInfo +cmsGetProfileInfoASCII = cmsGetProfileInfoASCII +cmsGetProfileContextID = cmsGetProfileContextID +cmsGetProfileVersion = cmsGetProfileVersion +cmsGetSupportedIntents = cmsGetSupportedIntents +cmsGetTagCount = cmsGetTagCount +cmsGetTagSignature = cmsGetTagSignature +cmsGetTransformContextID = cmsGetTransformContextID +_cmsICCcolorSpace = _cmsICCcolorSpace +_cmsIOPrintf = _cmsIOPrintf +cmsIsCLUT = cmsIsCLUT +cmsIsIntentSupported = cmsIsIntentSupported +cmsIsMatrixShaper = cmsIsMatrixShaper +cmsIsTag = cmsIsTag +cmsIsToneCurveDescending = cmsIsToneCurveDescending +cmsIsToneCurveLinear = cmsIsToneCurveLinear +cmsIsToneCurveMonotonic = cmsIsToneCurveMonotonic +cmsIsToneCurveMultisegment = cmsIsToneCurveMultisegment +cmsGetToneCurveParametricType = cmsGetToneCurveParametricType +cmsIT8Alloc = cmsIT8Alloc +cmsIT8DefineDblFormat = cmsIT8DefineDblFormat +cmsIT8EnumDataFormat = cmsIT8EnumDataFormat +cmsIT8EnumProperties = cmsIT8EnumProperties +cmsIT8EnumPropertyMulti = cmsIT8EnumPropertyMulti +cmsIT8Free = cmsIT8Free +cmsIT8GetData = cmsIT8GetData +cmsIT8GetDataDbl = cmsIT8GetDataDbl +cmsIT8FindDataFormat = cmsIT8FindDataFormat +cmsIT8GetDataRowCol = cmsIT8GetDataRowCol +cmsIT8GetDataRowColDbl = cmsIT8GetDataRowColDbl +cmsIT8GetPatchName = cmsIT8GetPatchName +cmsIT8GetPatchByName = cmsIT8GetPatchByName +cmsIT8GetProperty = cmsIT8GetProperty +cmsIT8GetPropertyDbl = cmsIT8GetPropertyDbl +cmsIT8GetPropertyMulti = cmsIT8GetPropertyMulti +cmsIT8GetSheetType = cmsIT8GetSheetType +cmsIT8LoadFromFile = cmsIT8LoadFromFile +cmsIT8LoadFromMem = cmsIT8LoadFromMem +cmsIT8SaveToFile = cmsIT8SaveToFile +cmsIT8SaveToMem = cmsIT8SaveToMem +cmsIT8SetComment = cmsIT8SetComment +cmsIT8SetData = cmsIT8SetData +cmsIT8SetDataDbl = cmsIT8SetDataDbl +cmsIT8SetDataFormat = cmsIT8SetDataFormat +cmsIT8SetDataRowCol = cmsIT8SetDataRowCol +cmsIT8SetDataRowColDbl = cmsIT8SetDataRowColDbl +cmsIT8SetPropertyDbl = cmsIT8SetPropertyDbl +cmsIT8SetPropertyHex = cmsIT8SetPropertyHex +cmsIT8SetPropertyStr = cmsIT8SetPropertyStr +cmsIT8SetPropertyMulti = cmsIT8SetPropertyMulti +cmsIT8SetPropertyUncooked = cmsIT8SetPropertyUncooked +cmsIT8SetSheetType = cmsIT8SetSheetType +cmsIT8SetTable = cmsIT8SetTable +cmsIT8SetTableByLabel = cmsIT8SetTableByLabel +cmsIT8SetIndexColumn = cmsIT8SetIndexColumn +cmsIT8TableCount = cmsIT8TableCount +cmsJoinToneCurve = cmsJoinToneCurve +cmsLab2LCh = cmsLab2LCh +cmsLab2XYZ = cmsLab2XYZ +cmsLabEncoded2Float = cmsLabEncoded2Float +cmsLabEncoded2FloatV2 = cmsLabEncoded2FloatV2 +cmsLCh2Lab = cmsLCh2Lab +_cmsLCMScolorSpace = _cmsLCMScolorSpace +cmsLinkTag = cmsLinkTag +cmsTagLinkedTo = cmsTagLinkedTo +cmsPipelineAlloc = cmsPipelineAlloc +cmsPipelineCat = cmsPipelineCat +cmsPipelineCheckAndRetreiveStages = cmsPipelineCheckAndRetreiveStages +cmsPipelineDup = cmsPipelineDup +cmsPipelineStageCount = cmsPipelineStageCount +cmsPipelineEval16 = cmsPipelineEval16 +cmsPipelineEvalFloat = cmsPipelineEvalFloat +cmsPipelineEvalReverseFloat = cmsPipelineEvalReverseFloat +cmsPipelineFree = cmsPipelineFree +cmsPipelineGetPtrToFirstStage = cmsPipelineGetPtrToFirstStage +cmsPipelineGetPtrToLastStage = cmsPipelineGetPtrToLastStage +cmsPipelineInputChannels = cmsPipelineInputChannels +cmsPipelineInsertStage = cmsPipelineInsertStage +cmsPipelineOutputChannels = cmsPipelineOutputChannels +cmsPipelineSetSaveAs8bitsFlag = cmsPipelineSetSaveAs8bitsFlag +_cmsPipelineSetOptimizationParameters = _cmsPipelineSetOptimizationParameters +cmsPipelineUnlinkStage = cmsPipelineUnlinkStage +_cmsMalloc = _cmsMalloc +_cmsMallocZero = _cmsMallocZero +_cmsMAT3eval = _cmsMAT3eval +_cmsMAT3identity = _cmsMAT3identity +_cmsMAT3inverse = _cmsMAT3inverse +_cmsMAT3isIdentity = _cmsMAT3isIdentity +_cmsMAT3per = _cmsMAT3per +_cmsMAT3solve = _cmsMAT3solve +cmsMD5computeID = cmsMD5computeID +cmsMLUalloc = cmsMLUalloc +cmsMLUdup = cmsMLUdup +cmsMLUfree = cmsMLUfree +cmsMLUgetASCII = cmsMLUgetASCII +cmsMLUgetTranslation = cmsMLUgetTranslation +cmsMLUgetWide = cmsMLUgetWide +cmsMLUsetASCII = cmsMLUsetASCII +cmsMLUsetWide = cmsMLUsetWide +cmsStageAllocCLut16bit = cmsStageAllocCLut16bit +cmsStageAllocCLut16bitGranular = cmsStageAllocCLut16bitGranular +cmsStageAllocCLutFloat = cmsStageAllocCLutFloat +cmsStageAllocCLutFloatGranular = cmsStageAllocCLutFloatGranular +cmsStageAllocToneCurves = cmsStageAllocToneCurves +cmsStageAllocIdentity = cmsStageAllocIdentity +cmsStageAllocMatrix = cmsStageAllocMatrix +_cmsStageAllocPlaceholder = _cmsStageAllocPlaceholder +cmsStageDup = cmsStageDup +cmsStageFree = cmsStageFree +cmsStageNext = cmsStageNext +cmsStageInputChannels = cmsStageInputChannels +cmsStageOutputChannels = cmsStageOutputChannels +cmsStageSampleCLut16bit = cmsStageSampleCLut16bit +cmsStageSampleCLutFloat = cmsStageSampleCLutFloat +cmsStageType = cmsStageType +cmsStageData = cmsStageData +cmsNamedColorCount = cmsNamedColorCount +cmsNamedColorIndex = cmsNamedColorIndex +cmsNamedColorInfo = cmsNamedColorInfo +cmsOpenIOhandlerFromFile = cmsOpenIOhandlerFromFile +cmsOpenIOhandlerFromMem = cmsOpenIOhandlerFromMem +cmsOpenIOhandlerFromNULL = cmsOpenIOhandlerFromNULL +cmsOpenIOhandlerFromStream = cmsOpenIOhandlerFromStream +cmsOpenProfileFromFile = cmsOpenProfileFromFile +cmsOpenProfileFromFileTHR = cmsOpenProfileFromFileTHR +cmsOpenProfileFromIOhandlerTHR = cmsOpenProfileFromIOhandlerTHR +cmsOpenProfileFromMem = cmsOpenProfileFromMem +cmsOpenProfileFromMemTHR = cmsOpenProfileFromMemTHR +cmsOpenProfileFromStream = cmsOpenProfileFromStream +cmsOpenProfileFromStreamTHR = cmsOpenProfileFromStreamTHR +cmsPlugin = cmsPlugin +_cmsRead15Fixed16Number = _cmsRead15Fixed16Number +_cmsReadAlignment = _cmsReadAlignment +_cmsReadFloat32Number = _cmsReadFloat32Number +cmsReadRawTag = cmsReadRawTag +cmsReadTag = cmsReadTag +_cmsReadTypeBase = _cmsReadTypeBase +_cmsReadUInt16Array = _cmsReadUInt16Array +_cmsReadUInt16Number = _cmsReadUInt16Number +_cmsReadUInt32Number = _cmsReadUInt32Number +_cmsReadUInt64Number = _cmsReadUInt64Number +_cmsReadUInt8Number = _cmsReadUInt8Number +_cmsReadXYZNumber = _cmsReadXYZNumber +_cmsRealloc = _cmsRealloc +cmsReverseToneCurve = cmsReverseToneCurve +cmsReverseToneCurveEx = cmsReverseToneCurveEx +cmsSaveProfileToFile = cmsSaveProfileToFile +cmsSaveProfileToIOhandler = cmsSaveProfileToIOhandler +cmsSaveProfileToMem = cmsSaveProfileToMem +cmsSaveProfileToStream = cmsSaveProfileToStream +cmsSetAdaptationState = cmsSetAdaptationState +cmsSetAlarmCodes = cmsSetAlarmCodes +cmsSetColorSpace = cmsSetColorSpace +cmsSetDeviceClass = cmsSetDeviceClass +cmsSetEncodedICCversion = cmsSetEncodedICCversion +cmsSetHeaderAttributes = cmsSetHeaderAttributes +cmsSetHeaderFlags = cmsSetHeaderFlags +cmsSetHeaderManufacturer = cmsSetHeaderManufacturer +cmsSetHeaderModel = cmsSetHeaderModel +cmsSetHeaderProfileID = cmsSetHeaderProfileID +cmsSetHeaderRenderingIntent = cmsSetHeaderRenderingIntent +cmsSetLogErrorHandler = cmsSetLogErrorHandler +cmsSetPCS = cmsSetPCS +cmsSetProfileVersion = cmsSetProfileVersion +cmsSignalError = cmsSignalError +cmsSmoothToneCurve = cmsSmoothToneCurve +cmsstrcasecmp = cmsstrcasecmp +cmsTempFromWhitePoint = cmsTempFromWhitePoint +cmsTransform2DeviceLink = cmsTransform2DeviceLink +cmsUnregisterPlugins = cmsUnregisterPlugins +_cmsVEC3cross = _cmsVEC3cross +_cmsVEC3distance = _cmsVEC3distance +_cmsVEC3dot = _cmsVEC3dot +_cmsVEC3init = _cmsVEC3init +_cmsVEC3length = _cmsVEC3length +_cmsVEC3minus = _cmsVEC3minus +cmsWhitePointFromTemp = cmsWhitePointFromTemp +_cmsWrite15Fixed16Number = _cmsWrite15Fixed16Number +_cmsWriteAlignment = _cmsWriteAlignment +_cmsWriteFloat32Number = _cmsWriteFloat32Number +cmsWriteRawTag = cmsWriteRawTag +cmsWriteTag = cmsWriteTag +_cmsWriteTypeBase = _cmsWriteTypeBase +_cmsWriteUInt16Array = _cmsWriteUInt16Array +_cmsWriteUInt16Number = _cmsWriteUInt16Number +_cmsWriteUInt32Number = _cmsWriteUInt32Number +_cmsWriteUInt64Number = _cmsWriteUInt64Number +_cmsWriteUInt8Number = _cmsWriteUInt8Number +_cmsWriteXYZNumber = _cmsWriteXYZNumber +cmsxyY2XYZ = cmsxyY2XYZ +cmsXYZ2Lab = cmsXYZ2Lab +cmsXYZ2xyY = cmsXYZ2xyY +cmsXYZEncoded2Float = cmsXYZEncoded2Float +cmsSliceSpace16 = cmsSliceSpace16 +cmsSliceSpaceFloat = cmsSliceSpaceFloat +cmsChangeBuffersFormat = cmsChangeBuffersFormat +cmsDictAlloc = cmsDictAlloc +cmsDictFree = cmsDictFree +cmsDictDup = cmsDictDup +cmsDictAddEntry = cmsDictAddEntry +cmsDictGetEntryList = cmsDictGetEntryList +cmsDictNextEntry = cmsDictNextEntry +_cmsGetTransformUserData = _cmsGetTransformUserData +_cmsSetTransformUserData = _cmsSetTransformUserData +_cmsGetTransformFormatters16 = _cmsGetTransformFormatters16 +_cmsGetTransformFormattersFloat = _cmsGetTransformFormattersFloat +cmsGetHeaderCreator = cmsGetHeaderCreator +cmsPluginTHR = cmsPluginTHR +cmsGetPipelineContextID = cmsGetPipelineContextID +cmsGetTransformInputFormat = cmsGetTransformInputFormat +cmsGetTransformOutputFormat = cmsGetTransformOutputFormat +cmsCreateContext = cmsCreateContext +cmsDupContext = cmsDupContext +cmsDeleteContext = cmsDeleteContext +cmsGetContextUserData = cmsGetContextUserData +cmsUnregisterPluginsTHR = cmsUnregisterPluginsTHR +cmsSetAlarmCodesTHR = cmsSetAlarmCodesTHR +cmsGetAlarmCodesTHR = cmsGetAlarmCodesTHR +cmsSetAdaptationStateTHR = cmsSetAdaptationStateTHR +cmsSetLogErrorHandlerTHR = cmsSetLogErrorHandlerTHR +cmsGetSupportedIntentsTHR = cmsGetSupportedIntentsTHR +cmsMLUtranslationsCount = cmsMLUtranslationsCount +cmsMLUtranslationsCodes = cmsMLUtranslationsCodes +_cmsCreateMutex = _cmsCreateMutex +_cmsDestroyMutex = _cmsDestroyMutex +_cmsLockMutex = _cmsLockMutex +_cmsUnlockMutex = _cmsUnlockMutex \ No newline at end of file diff -Nru lcms2-2.5/src/lcms2_internal.h lcms2-2.6/src/lcms2_internal.h --- lcms2-2.5/src/lcms2_internal.h 2013-06-27 16:01:28.000000000 +0000 +++ lcms2-2.6/src/lcms2_internal.h 2014-03-17 16:09:30.000000000 +0000 @@ -1,7 +1,7 @@ // // Little Color Management System -// Copyright (c) 1998-2011 Marti Maria Saguer +// Copyright (c) 1998-2014 Marti Maria Saguer // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the "Software"), @@ -164,16 +164,171 @@ return _cmsQuickFloorWord(d); } -// Plug-In registering --------------------------------------------------------------- + +// Pthread support -------------------------------------------------------------------- +#ifndef CMS_NO_PTHREADS + +// This is the threading support. Unfortunately, it has to be platform-dependent because +// windows does not support pthreads. + +#ifdef CMS_IS_WINDOWS_ + +#define WIN32_LEAN_AND_MEAN 1 +#include + + +// From: http://locklessinc.com/articles/pthreads_on_windows/ +// The pthreads API has an initialization macro that has no correspondence to anything in +// the windows API. By investigating the internal definition of the critical section type, +// one may work out how to initialize one without calling InitializeCriticalSection(). +// The trick here is that InitializeCriticalSection() is not allowed to fail. It tries +// to allocate a critical section debug object, but if no memory is available, it sets +// the pointer to a specific value. (One would expect that value to be NULL, but it is +// actually (void *)-1 for some reason.) Thus we can use this special value for that +// pointer, and the critical section code will work. + +// The other important part of the critical section type to initialize is the number +// of waiters. This controls whether or not the mutex is locked. Fortunately, this +// part of the critical section is unlikely to change. Apparently, many programs +// already test critical sections to see if they are locked using this value, so +// Microsoft felt that it was necessary to keep it set at -1 for an unlocked critical +// section, even when they changed the underlying algorithm to be more scalable. +// The final parts of the critical section object are unimportant, and can be set +// to zero for their defaults. This yields an initialization macro: + +typedef CRITICAL_SECTION _cmsMutex; + +#define CMS_MUTEX_INITIALIZER {(void*) -1,-1,0,0,0,0} + +cmsINLINE int _cmsLockPrimitive(_cmsMutex *m) +{ + EnterCriticalSection(m); + return 0; +} + +cmsINLINE int _cmsUnlockPrimitive(_cmsMutex *m) +{ + LeaveCriticalSection(m); + return 0; +} + +cmsINLINE int _cmsInitMutexPrimitive(_cmsMutex *m) +{ + InitializeCriticalSection(m); + return 0; +} + +cmsINLINE int _cmsDestroyMutexPrimitive(_cmsMutex *m) +{ + DeleteCriticalSection(m); + return 0; +} + +cmsINLINE int _cmsEnterCriticalSectionPrimitive(_cmsMutex *m) +{ + EnterCriticalSection(m); + return 0; +} + +cmsINLINE int _cmsLeaveCriticalSectionPrimitive(_cmsMutex *m) +{ + LeaveCriticalSection(m); + return 0; +} + +#else + +// Rest of the wide world +#include + +#define CMS_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER +typedef pthread_mutex_t _cmsMutex; + + +cmsINLINE int _cmsLockPrimitive(_cmsMutex *m) +{ + return pthread_mutex_lock(m); +} + +cmsINLINE int _cmsUnlockPrimitive(_cmsMutex *m) +{ + return pthread_mutex_unlock(m); +} + +cmsINLINE int _cmsInitMutexPrimitive(_cmsMutex *m) +{ + return pthread_mutex_init(m, NULL); +} + +cmsINLINE int _cmsDestroyMutexPrimitive(_cmsMutex *m) +{ + return pthread_mutex_destroy(m); +} + +cmsINLINE int _cmsEnterCriticalSectionPrimitive(_cmsMutex *m) +{ + return pthread_mutex_lock(m); +} + +cmsINLINE int _cmsLeaveCriticalSectionPrimitive(_cmsMutex *m) +{ + return pthread_mutex_unlock(m); +} + +#endif +#else + +#define CMS_MUTEX_INITIALIZER 0 +typedef int _cmsMutex; + + +cmsINLINE int _cmsLockPrimitive(_cmsMutex *m) +{ + return 0; + cmsUNUSED_PARAMETER(m); +} + +cmsINLINE int _cmsUnlockPrimitive(_cmsMutex *m) +{ + return 0; + cmsUNUSED_PARAMETER(m); +} + +cmsINLINE int _cmsInitMutexPrimitive(_cmsMutex *m) +{ + return 0; + cmsUNUSED_PARAMETER(m); +} + +cmsINLINE int _cmsDestroyMutexPrimitive(_cmsMutex *m) +{ + return 0; + cmsUNUSED_PARAMETER(m); +} + +cmsINLINE int _cmsEnterCriticalSectionPrimitive(_cmsMutex *m) +{ + return 0; + cmsUNUSED_PARAMETER(m); +} + +cmsINLINE int _cmsLeaveCriticalSectionPrimitive(_cmsMutex *m) +{ + return 0; + cmsUNUSED_PARAMETER(m); +} +#endif + +// Plug-In registration --------------------------------------------------------------- // Specialized function for plug-in memory management. No pairing free() since whole pool is freed at once. void* _cmsPluginMalloc(cmsContext ContextID, cmsUInt32Number size); // Memory management -cmsBool _cmsRegisterMemHandlerPlugin(cmsPluginBase* Plugin); +cmsBool _cmsRegisterMemHandlerPlugin(cmsContext ContextID, cmsPluginBase* Plugin); // Interpolation -cmsBool _cmsRegisterInterpPlugin(cmsPluginBase* Plugin); +cmsBool _cmsRegisterInterpPlugin(cmsContext ContextID, cmsPluginBase* Plugin); // Parametric curves cmsBool _cmsRegisterParametricCurvesPlugin(cmsContext ContextID, cmsPluginBase* Plugin); @@ -199,9 +354,12 @@ // Transform cmsBool _cmsRegisterTransformPlugin(cmsContext ContextID, cmsPluginBase* Plugin); +// Mutex +cmsBool _cmsRegisterMutexPlugin(cmsContext ContextID, cmsPluginBase* Plugin); + // --------------------------------------------------------------------------------------------------------- -// Suballocators. Those are blocks of memory that is freed at the end on whole block. +// Suballocators. typedef struct _cmsSubAllocator_chunk_st { cmsUInt8Number* Block; @@ -224,9 +382,264 @@ _cmsSubAllocator* _cmsCreateSubAlloc(cmsContext ContextID, cmsUInt32Number Initial); void _cmsSubAllocDestroy(_cmsSubAllocator* s); void* _cmsSubAlloc(_cmsSubAllocator* s, cmsUInt32Number size); +void* _cmsSubAllocDup(_cmsSubAllocator* s, const void *ptr, cmsUInt32Number size); // ---------------------------------------------------------------------------------- +// The context clients. +typedef enum { + + UserPtr, // User-defined pointer + Logger, + AlarmCodesContext, + AdaptationStateContext, + MemPlugin, + InterpPlugin, + CurvesPlugin, + FormattersPlugin, + TagTypePlugin, + TagPlugin, + IntentPlugin, + MPEPlugin, + OptimizationPlugin, + TransformPlugin, + MutexPlugin, + + // Last in list + MemoryClientMax + +} _cmsMemoryClient; + + +// Container for memory management plug-in. +typedef struct { + + _cmsMallocFnPtrType MallocPtr; + _cmsMalloZerocFnPtrType MallocZeroPtr; + _cmsFreeFnPtrType FreePtr; + _cmsReallocFnPtrType ReallocPtr; + _cmsCallocFnPtrType CallocPtr; + _cmsDupFnPtrType DupPtr; + +} _cmsMemPluginChunkType; + +// Copy memory management function pointers from plug-in to chunk, taking care of missing routines +void _cmsInstallAllocFunctions(cmsPluginMemHandler* Plugin, _cmsMemPluginChunkType* ptr); + +// Internal structure for context +struct _cmsContext_struct { + + struct _cmsContext_struct* Next; // Points to next context in the new style + _cmsSubAllocator* MemPool; // The memory pool that stores context data + + void* chunks[MemoryClientMax]; // array of pointers to client chunks. Memory itself is hold in the suballocator. + // If NULL, then it reverts to global Context0 + + _cmsMemPluginChunkType DefaultMemoryManager; // The allocators used for creating the context itself. Cannot be overriden +}; + +// Returns a pointer to a valid context structure, including the global one if id is zero. +// Verifies the magic number. +struct _cmsContext_struct* _cmsGetContext(cmsContext ContextID); + +// Returns the block assigned to the specific zone. +void* _cmsContextGetClientChunk(cmsContext id, _cmsMemoryClient mc); + + +// Chunks of context memory by plug-in client ------------------------------------------------------- + +// Those structures encapsulates all variables needed by the several context clients (mostly plug-ins) + +// Container for error logger -- not a plug-in +typedef struct { + + cmsLogErrorHandlerFunction LogErrorHandler; // Set to NULL for Context0 fallback + +} _cmsLogErrorChunkType; + +// The global Context0 storage for error logger +extern _cmsLogErrorChunkType _cmsLogErrorChunk; + +// Allocate and init error logger container. +void _cmsAllocLogErrorChunk(struct _cmsContext_struct* ctx, + const struct _cmsContext_struct* src); + +// Container for alarm codes -- not a plug-in +typedef struct { + + cmsUInt16Number AlarmCodes[cmsMAXCHANNELS]; + +} _cmsAlarmCodesChunkType; + +// The global Context0 storage for alarm codes +extern _cmsAlarmCodesChunkType _cmsAlarmCodesChunk; + +// Allocate and init alarm codes container. +void _cmsAllocAlarmCodesChunk(struct _cmsContext_struct* ctx, + const struct _cmsContext_struct* src); + +// Container for adaptation state -- not a plug-in +typedef struct { + + cmsFloat64Number AdaptationState; + +} _cmsAdaptationStateChunkType; + +// The global Context0 storage for adaptation state +extern _cmsAdaptationStateChunkType _cmsAdaptationStateChunk; + +// Allocate and init adaptation state container. +void _cmsAllocAdaptationStateChunk(struct _cmsContext_struct* ctx, + const struct _cmsContext_struct* src); + + +// The global Context0 storage for memory management +extern _cmsMemPluginChunkType _cmsMemPluginChunk; + +// Allocate and init memory management container. +void _cmsAllocMemPluginChunk(struct _cmsContext_struct* ctx, + const struct _cmsContext_struct* src); + +// Container for interpolation plug-in +typedef struct { + + cmsInterpFnFactory Interpolators; + +} _cmsInterpPluginChunkType; + +// The global Context0 storage for interpolation plug-in +extern _cmsInterpPluginChunkType _cmsInterpPluginChunk; + +// Allocate and init interpolation container. +void _cmsAllocInterpPluginChunk(struct _cmsContext_struct* ctx, + const struct _cmsContext_struct* src); + +// Container for parametric curves plug-in +typedef struct { + + struct _cmsParametricCurvesCollection_st* ParametricCurves; + +} _cmsCurvesPluginChunkType; + +// The global Context0 storage for tone curves plug-in +extern _cmsCurvesPluginChunkType _cmsCurvesPluginChunk; + +// Allocate and init parametric curves container. +void _cmsAllocCurvesPluginChunk(struct _cmsContext_struct* ctx, + const struct _cmsContext_struct* src); + +// Container for formatters plug-in +typedef struct { + + struct _cms_formatters_factory_list* FactoryList; + +} _cmsFormattersPluginChunkType; + +// The global Context0 storage for formatters plug-in +extern _cmsFormattersPluginChunkType _cmsFormattersPluginChunk; + +// Allocate and init formatters container. +void _cmsAllocFormattersPluginChunk(struct _cmsContext_struct* ctx, + const struct _cmsContext_struct* src); + +// This chunk type is shared by TagType plug-in and MPE Plug-in +typedef struct { + + struct _cmsTagTypeLinkedList_st* TagTypes; + +} _cmsTagTypePluginChunkType; + + +// The global Context0 storage for tag types plug-in +extern _cmsTagTypePluginChunkType _cmsTagTypePluginChunk; + + +// The global Context0 storage for mult process elements plug-in +extern _cmsTagTypePluginChunkType _cmsMPETypePluginChunk; + +// Allocate and init Tag types container. +void _cmsAllocTagTypePluginChunk(struct _cmsContext_struct* ctx, + const struct _cmsContext_struct* src); +// Allocate and init MPE container. +void _cmsAllocMPETypePluginChunk(struct _cmsContext_struct* ctx, + const struct _cmsContext_struct* src); +// Container for tag plug-in +typedef struct { + + struct _cmsTagLinkedList_st* Tag; + +} _cmsTagPluginChunkType; + + +// The global Context0 storage for tag plug-in +extern _cmsTagPluginChunkType _cmsTagPluginChunk; + +// Allocate and init Tag container. +void _cmsAllocTagPluginChunk(struct _cmsContext_struct* ctx, + const struct _cmsContext_struct* src); + +// Container for intents plug-in +typedef struct { + + struct _cms_intents_list* Intents; + +} _cmsIntentsPluginChunkType; + + +// The global Context0 storage for intents plug-in +extern _cmsIntentsPluginChunkType _cmsIntentsPluginChunk; + +// Allocate and init intents container. +void _cmsAllocIntentsPluginChunk(struct _cmsContext_struct* ctx, + const struct _cmsContext_struct* src); + +// Container for optimization plug-in +typedef struct { + + struct _cmsOptimizationCollection_st* OptimizationCollection; + +} _cmsOptimizationPluginChunkType; + + +// The global Context0 storage for optimizers plug-in +extern _cmsOptimizationPluginChunkType _cmsOptimizationPluginChunk; + +// Allocate and init optimizers container. +void _cmsAllocOptimizationPluginChunk(struct _cmsContext_struct* ctx, + const struct _cmsContext_struct* src); + +// Container for transform plug-in +typedef struct { + + struct _cmsTransformCollection_st* TransformCollection; + +} _cmsTransformPluginChunkType; + +// The global Context0 storage for full-transform replacement plug-in +extern _cmsTransformPluginChunkType _cmsTransformPluginChunk; + +// Allocate and init transform container. +void _cmsAllocTransformPluginChunk(struct _cmsContext_struct* ctx, + const struct _cmsContext_struct* src); + +// Container for mutex plug-in +typedef struct { + + _cmsCreateMutexFnPtrType CreateMutexPtr; + _cmsDestroyMutexFnPtrType DestroyMutexPtr; + _cmsLockMutexFnPtrType LockMutexPtr; + _cmsUnlockMutexFnPtrType UnlockMutexPtr; + +} _cmsMutexPluginChunkType; + +// The global Context0 storage for mutex plug-in +extern _cmsMutexPluginChunkType _cmsMutexPluginChunk; + +// Allocate and init mutex container. +void _cmsAllocMutexPluginChunk(struct _cmsContext_struct* ctx, + const struct _cmsContext_struct* src); + +// ---------------------------------------------------------------------------------- // MLU internal representation typedef struct { @@ -318,10 +731,14 @@ cmsBool TagSaveAsRaw[MAX_TABLE_TAG]; // True to write uncooked void * TagPtrs[MAX_TABLE_TAG]; cmsTagTypeHandler* TagTypeHandlers[MAX_TABLE_TAG]; // Same structure may be serialized on different types - // depending on profile version, so we keep track of the // type handler for each tag in the list. + // depending on profile version, so we keep track of the + // type handler for each tag in the list. // Special cmsBool IsWrite; + // Keep a mutex for cmsReadTag -- Note that this only works if the user includes a mutex plugin + void * UsrMutex; + } _cmsICCPROFILE; // IO helpers for profiles @@ -330,9 +747,9 @@ int _cmsSearchTag(_cmsICCPROFILE* Icc, cmsTagSignature sig, cmsBool lFollowLinks); // Tag types -cmsTagTypeHandler* _cmsGetTagTypeHandler(cmsTagTypeSignature sig); +cmsTagTypeHandler* _cmsGetTagTypeHandler(cmsContext ContextID, cmsTagTypeSignature sig); cmsTagTypeSignature _cmsGetTagTrueType(cmsHPROFILE hProfile, cmsTagSignature sig); -cmsTagDescriptor* _cmsGetTagDescriptor(cmsTagSignature sig); +cmsTagDescriptor* _cmsGetTagDescriptor(cmsContext ContextID, cmsTagSignature sig); // Error logging --------------------------------------------------------------------------------------------------------- @@ -343,7 +760,7 @@ cmsInterpParams* _cmsComputeInterpParams(cmsContext ContextID, int nSamples, int InputChan, int OutputChan, const void* Table, cmsUInt32Number dwFlags); cmsInterpParams* _cmsComputeInterpParamsEx(cmsContext ContextID, const cmsUInt32Number nSamples[], int InputChan, int OutputChan, const void* Table, cmsUInt32Number dwFlags); void _cmsFreeInterpParams(cmsInterpParams* p); -cmsBool _cmsSetInterpolationRoutine(cmsInterpParams* p); +cmsBool _cmsSetInterpolationRoutine(cmsContext ContextID, cmsInterpParams* p); // Curves ---------------------------------------------------------------------------------------------------------------- @@ -474,7 +891,8 @@ cmsUInt16Number **Black, cmsUInt32Number *nOutputs); -cmsBool _cmsOptimizePipeline(cmsPipeline** Lut, +cmsBool _cmsOptimizePipeline(cmsContext ContextID, + cmsPipeline** Lut, int Intent, cmsUInt32Number* InputFormat, cmsUInt32Number* OutputFormat, @@ -499,7 +917,8 @@ cmsBool _cmsFormatterIsFloat(cmsUInt32Number Type); cmsBool _cmsFormatterIs8bit(cmsUInt32Number Type); -cmsFormatter _cmsGetFormatter(cmsUInt32Number Type, // Specific type, i.e. TYPE_RGB_8 +cmsFormatter _cmsGetFormatter(cmsContext ContextID, + cmsUInt32Number Type, // Specific type, i.e. TYPE_RGB_8 cmsFormatterDirection Dir, cmsUInt32Number dwFlags); diff -Nru lcms2-2.5/src/Makefile.in lcms2-2.6/src/Makefile.in --- lcms2-2.5/src/Makefile.in 2013-06-27 16:01:28.000000000 +0000 +++ lcms2-2.6/src/Makefile.in 2014-03-17 16:09:30.000000000 +0000 @@ -58,7 +58,8 @@ subdir = src DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/configure.ac +am__aclocal_m4_deps = $(top_srcdir)/m4/acx_pthread.m4 \ + $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d @@ -175,6 +176,7 @@ LIBTOOL_DEPS = @LIBTOOL_DEPS@ LIB_JPEG = @LIB_JPEG@ LIB_MATH = @LIB_MATH@ +LIB_THREAD = @LIB_THREAD@ LIB_TIFF = @LIB_TIFF@ LIB_ZLIB = @LIB_ZLIB@ LIPO = @LIPO@ @@ -198,6 +200,10 @@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ +PTHREAD_CC = @PTHREAD_CC@ +PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ +PTHREAD_CXX = @PTHREAD_CXX@ +PTHREAD_LIBS = @PTHREAD_LIBS@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ @@ -213,6 +219,7 @@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +acx_pthread_config = @acx_pthread_config@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ Binary files /tmp/PwkAlo6nzi/lcms2-2.5/testbed/ibm-t61.icc and /tmp/bYaH4ACarr/lcms2-2.6/testbed/ibm-t61.icc differ diff -Nru lcms2-2.5/testbed/Makefile.am lcms2-2.6/testbed/Makefile.am --- lcms2-2.5/testbed/Makefile.am 2013-06-27 16:01:28.000000000 +0000 +++ lcms2-2.6/testbed/Makefile.am 2014-03-17 16:09:30.000000000 +0000 @@ -13,11 +13,11 @@ testcms_LDADD = $(top_builddir)/src/liblcms2.la testcms_LDFLAGS = @LDFLAGS@ -testcms_SOURCES = testcms2.c +testcms_SOURCES = testcms2.c testplugin.c zoo_icc.c testcms2.h EXTRA_DIST = test1.icc bad.icc toosmall.icc test2.icc \ test3.icc test4.icc \ - test5.icc + test5.icc ibm-t61.icc check: if [ $(top_srcdir) != $(top_builddir) ]; then \ diff -Nru lcms2-2.5/testbed/Makefile.in lcms2-2.6/testbed/Makefile.in --- lcms2-2.5/testbed/Makefile.in 2013-06-27 16:01:28.000000000 +0000 +++ lcms2-2.6/testbed/Makefile.in 2014-03-17 16:09:30.000000000 +0000 @@ -58,13 +58,15 @@ subdir = testbed DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/configure.ac +am__aclocal_m4_deps = $(top_srcdir)/m4/acx_pthread.m4 \ + $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = -am_testcms_OBJECTS = testcms2.$(OBJEXT) +am_testcms_OBJECTS = testcms2.$(OBJEXT) testplugin.$(OBJEXT) \ + zoo_icc.$(OBJEXT) testcms_OBJECTS = $(am_testcms_OBJECTS) testcms_DEPENDENCIES = $(top_builddir)/src/liblcms2.la testcms_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ @@ -141,6 +143,7 @@ LIBTOOL_DEPS = @LIBTOOL_DEPS@ LIB_JPEG = @LIB_JPEG@ LIB_MATH = @LIB_MATH@ +LIB_THREAD = @LIB_THREAD@ LIB_TIFF = @LIB_TIFF@ LIB_ZLIB = @LIB_ZLIB@ LIPO = @LIPO@ @@ -164,6 +167,10 @@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ +PTHREAD_CC = @PTHREAD_CC@ +PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ +PTHREAD_CXX = @PTHREAD_CXX@ +PTHREAD_LIBS = @PTHREAD_LIBS@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ @@ -179,6 +186,7 @@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +acx_pthread_config = @acx_pthread_config@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ @@ -233,10 +241,10 @@ # CFLAGS = --pedantic -Wall -std=c99 -O2 testcms_LDADD = $(top_builddir)/src/liblcms2.la testcms_LDFLAGS = @LDFLAGS@ -testcms_SOURCES = testcms2.c +testcms_SOURCES = testcms2.c testplugin.c zoo_icc.c testcms2.h EXTRA_DIST = test1.icc bad.icc toosmall.icc test2.icc \ test3.icc test4.icc \ - test5.icc + test5.icc ibm-t61.icc all: all-am @@ -292,6 +300,8 @@ -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testcms2.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testplugin.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/zoo_icc.Po@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< Binary files /tmp/PwkAlo6nzi/lcms2-2.5/testbed/new.icc and /tmp/bYaH4ACarr/lcms2-2.6/testbed/new.icc differ diff -Nru lcms2-2.5/testbed/testcms2.c lcms2-2.6/testbed/testcms2.c --- lcms2-2.5/testbed/testcms2.c 2013-06-27 16:01:28.000000000 +0000 +++ lcms2-2.6/testbed/testcms2.c 2014-03-17 16:09:30.000000000 +0000 @@ -1,7 +1,7 @@ //--------------------------------------------------------------------------------- // // Little Color Management System -// Copyright (c) 1998-2010 Marti Maria Saguer +// Copyright (c) 1998-2014 Marti Maria Saguer // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the "Software"), @@ -24,11 +24,8 @@ //--------------------------------------------------------------------------------- // -#ifdef _MSC_VER -# define _CRT_SECURE_NO_WARNINGS 1 -#endif -#include "lcms2_internal.h" +#include "testcms2.h" // On Visual Studio, use debug CRT #ifdef _MSC_VER @@ -55,7 +52,6 @@ #define cmsmin(a, b) (((a) < (b)) ? (a) : (b)) // Die, a fatal unexpected error is detected! -static void Die(const char* Reason) { printf("\n\nArrrgggg!!: %s!\n\n", Reason); @@ -75,6 +71,7 @@ typedef struct { cmsUInt32Number KeepSize; cmsContext WhoAllocated; + cmsUInt32Number DontCheck; union { cmsUInt64Number HiSparc; @@ -100,7 +97,7 @@ { static cmsUInt32Number n = 1; - return (cmsContext) n++; + return (cmsContext) (n++ % 0xff0); } // The allocate routine @@ -126,10 +123,12 @@ blk ->KeepSize = size; blk ->WhoAllocated = ContextID; + blk ->DontCheck = 0; return (void*) ((cmsUInt8Number*) blk + SIZE_OF_MEM_HEADER); } + // The free routine static void DebugFree(cmsContext ContextID, void *Ptr) @@ -143,13 +142,14 @@ blk = (_cmsMemoryBlock*) (((cmsUInt8Number*) Ptr) - SIZE_OF_MEM_HEADER); TotalMemory -= blk ->KeepSize; - if (blk ->WhoAllocated != ContextID) { + if (blk ->WhoAllocated != ContextID && !blk->DontCheck) { Die("Trying to free memory allocated by a different thread"); } free(blk); } + // Reallocate, just a malloc, a copy and a free in this case. static void * DebugRealloc(cmsContext ContextID, void* Ptr, cmsUInt32Number NewSize) @@ -177,11 +177,68 @@ printf("Allocated = %u MaxAlloc = %u Single block hit = %u\n", TotalMemory, MaxAllocated, SingleHit); } + +void DebugMemDontCheckThis(void *Ptr) +{ + _cmsMemoryBlock* blk = (_cmsMemoryBlock*) (((cmsUInt8Number*) Ptr) - SIZE_OF_MEM_HEADER); + + blk ->DontCheck = 1; +} + + +// Memory string +static +const char* MemStr(cmsUInt32Number size) +{ + static char Buffer[1024]; + + if (size > 1024*1024) { + sprintf(Buffer, "%g Mb", (cmsFloat64Number) size / (1024.0*1024.0)); + } + else + if (size > 1024) { + sprintf(Buffer, "%g Kb", (cmsFloat64Number) size / 1024.0); + } + else + sprintf(Buffer, "%g bytes", (cmsFloat64Number) size); + + return Buffer; +} + + +void TestMemoryLeaks(cmsBool ok) +{ + if (TotalMemory > 0) + printf("Ok, but %s are left!\n", MemStr(TotalMemory)); + else { + if (ok) printf("Ok.\n"); + } +} + // Here we go with the plug-in declaration -static cmsPluginMemHandler DebugMemHandler = {{ cmsPluginMagicNumber, 2000, cmsPluginMemHandlerSig, NULL }, +static cmsPluginMemHandler DebugMemHandler = {{ cmsPluginMagicNumber, 2060, cmsPluginMemHandlerSig, NULL }, DebugMalloc, DebugFree, DebugRealloc, NULL, NULL, NULL }; -// Utils ------------------------------------------------------------------------------------- +// Returnds a pointer to the memhandler plugin +void* PluginMemHandler(void) +{ + return (void*) &DebugMemHandler; +} + +cmsContext WatchDogContext(void* usr) +{ + cmsContext ctx; + + ctx = cmsCreateContext(&DebugMemHandler, usr); + + if (ctx == NULL) + Die("Unable to create memory managed context"); + + DebugMemDontCheckThis(ctx); + return ctx; +} + + static void FatalErrorQuit(cmsContext ContextID, cmsUInt32Number ErrorCode, const char *Text) @@ -190,18 +247,29 @@ cmsUNUSED_PARAMETER(ContextID); cmsUNUSED_PARAMETER(ErrorCode); +} + +void ResetFatalError(void) +{ + cmsSetLogErrorHandler(FatalErrorQuit); } + // Print a dot for gauging -static void Dot(void) { fprintf(stdout, "."); fflush(stdout); } +void Say(const char* str) +{ + fprintf(stdout, "%s", str); fflush(stdout); +} + + // Keep track of the reason to fail -static + void Fail(const char* frm, ...) { va_list args; @@ -211,7 +279,7 @@ } // Keep track of subtest -static + void SubTest(const char* frm, ...) { va_list args; @@ -222,27 +290,6 @@ va_end(args); } - -// Memory string -static -const char* MemStr(cmsUInt32Number size) -{ - static char Buffer[1024]; - - if (size > 1024*1024) { - sprintf(Buffer, "%g Mb", (cmsFloat64Number) size / (1024.0*1024.0)); - } - else - if (size > 1024) { - sprintf(Buffer, "%g Kb", (cmsFloat64Number) size / 1024.0); - } - else - sprintf(Buffer, "%g bytes", (cmsFloat64Number) size); - - return Buffer; -} - - // The check framework static void Check(const char* Title, TestFn Fn) @@ -259,10 +306,8 @@ if (Fn() && !TrappedError) { // It is a good place to check memory - if (TotalMemory > 0) - printf("Ok, but %s are left!\n", MemStr(TotalMemory)); - else - printf("Ok.\n"); + TestMemoryLeaks(TRUE); + } else { printf("FAIL!\n"); @@ -571,11 +616,8 @@ h = cmsOpenProfileFromFile(FileName, "r"); if (h == NULL) return 0; - - // Do some teste.... - + cmsCloseProfile(h); - return 1; } @@ -744,7 +786,7 @@ (_cmsQuickFloor(-32767.1) != -32768)) { Fail("\nOOOPPSS! _cmsQuickFloor() does not work as expected in your machine!\n\n" - "Please, edit lcms.h and uncomment the CMS_DONT_USE_FAST_FLOOR toggle.\n"); + "Please, edit lcms2.h and uncomment the CMS_DONT_USE_FAST_FLOOR toggle.\n"); return 0; } @@ -763,7 +805,7 @@ if (_cmsQuickFloorWord((cmsFloat64Number) i + 0.1234) != i) { Fail("\nOOOPPSS! _cmsQuickFloorWord() does not work as expected in your machine!\n\n" - "Please, edit lcms.h and uncomment the CMS_DONT_USE_FAST_FLOOR toggle.\n"); + "Please, edit lcms2.h and uncomment the CMS_DONT_USE_FAST_FLOOR toggle.\n"); return 0; } } @@ -787,7 +829,6 @@ static cmsFloat64Number MaxErr; static cmsFloat64Number AllowedErr = FIXED_PRECISION_15_16; -static cmsBool IsGoodVal(const char *title, cmsFloat64Number in, cmsFloat64Number out, cmsFloat64Number max) { cmsFloat64Number Err = fabs(in - out); @@ -803,19 +844,18 @@ return TRUE; } -static + cmsBool IsGoodFixed15_16(const char *title, cmsFloat64Number in, cmsFloat64Number out) { return IsGoodVal(title, in, out, FIXED_PRECISION_15_16); } -static + cmsBool IsGoodFixed8_8(const char *title, cmsFloat64Number in, cmsFloat64Number out) { return IsGoodVal(title, in, out, FIXED_PRECISION_8_8); } -static cmsBool IsGoodWord(const char *title, cmsUInt16Number in, cmsUInt16Number out) { if ((abs(in - out) > 0 )) { @@ -827,7 +867,6 @@ return TRUE; } -static cmsBool IsGoodWordPrec(const char *title, cmsUInt16Number in, cmsUInt16Number out, cmsUInt16Number maxErr) { if ((abs(in - out) > maxErr )) { @@ -891,6 +930,59 @@ return 1; } +// D50 constant -------------------------------------------------------------------------------------------- + +static +cmsInt32Number CheckD50Roundtrip(void) +{ + cmsFloat64Number cmsD50X_2 = 0.96420288; + cmsFloat64Number cmsD50Y_2 = 1.0; + cmsFloat64Number cmsD50Z_2 = 0.82490540; + + cmsS15Fixed16Number xe = _cmsDoubleTo15Fixed16(cmsD50X); + cmsS15Fixed16Number ye = _cmsDoubleTo15Fixed16(cmsD50Y); + cmsS15Fixed16Number ze = _cmsDoubleTo15Fixed16(cmsD50Z); + + cmsFloat64Number x = _cms15Fixed16toDouble(xe); + cmsFloat64Number y = _cms15Fixed16toDouble(ye); + cmsFloat64Number z = _cms15Fixed16toDouble(ze); + + double dx = fabs(cmsD50X - x); + double dy = fabs(cmsD50Y - y); + double dz = fabs(cmsD50Z - z); + + double euc = sqrt(dx*dx + dy*dy + dz* dz); + + if (euc > 1E-5) { + + Fail("D50 roundtrip |err| > (%f) ", euc); + return 0; + } + + xe = _cmsDoubleTo15Fixed16(cmsD50X_2); + ye = _cmsDoubleTo15Fixed16(cmsD50Y_2); + ze = _cmsDoubleTo15Fixed16(cmsD50Z_2); + + x = _cms15Fixed16toDouble(xe); + y = _cms15Fixed16toDouble(ye); + z = _cms15Fixed16toDouble(ze); + + dx = fabs(cmsD50X_2 - x); + dy = fabs(cmsD50Y_2 - y); + dz = fabs(cmsD50Z_2 - z); + + euc = sqrt(dx*dx + dy*dy + dz* dz); + + if (euc > 1E-5) { + + Fail("D50 roundtrip |err| > (%f) ", euc); + return 0; + } + + + return 1; +} + // Linear interpolation ----------------------------------------------------------------------------------------------- // Since prime factors of 65535 (FFFF) are, @@ -3664,7 +3756,7 @@ static cmsBool FormatterFailed; static -void CheckSingleFormatter16(cmsUInt32Number Type, const char* Text) +void CheckSingleFormatter16(cmsContext id, cmsUInt32Number Type, const char* Text) { cmsUInt16Number Values[cmsMAXCHANNELS]; cmsUInt8Number Buffer[1024]; @@ -3679,16 +3771,16 @@ info.OutputFormat = info.InputFormat = Type; // Go forth and back - f = _cmsGetFormatter(Type, cmsFormatterInput, CMS_PACK_FLAGS_16BITS); - b = _cmsGetFormatter(Type, cmsFormatterOutput, CMS_PACK_FLAGS_16BITS); + f = _cmsGetFormatter(id, Type, cmsFormatterInput, CMS_PACK_FLAGS_16BITS); + b = _cmsGetFormatter(id, Type, cmsFormatterOutput, CMS_PACK_FLAGS_16BITS); if (f.Fmt16 == NULL || b.Fmt16 == NULL) { Fail("no formatter for %s", Text); FormatterFailed = TRUE; // Useful for debug - f = _cmsGetFormatter(Type, cmsFormatterInput, CMS_PACK_FLAGS_16BITS); - b = _cmsGetFormatter(Type, cmsFormatterOutput, CMS_PACK_FLAGS_16BITS); + f = _cmsGetFormatter(id, Type, cmsFormatterInput, CMS_PACK_FLAGS_16BITS); + b = _cmsGetFormatter(id, Type, cmsFormatterOutput, CMS_PACK_FLAGS_16BITS); return; } @@ -3733,7 +3825,7 @@ } } -#define C(a) CheckSingleFormatter16(a, #a) +#define C(a) CheckSingleFormatter16(0, a, #a) // Check all formatters @@ -3931,16 +4023,16 @@ info.OutputFormat = info.InputFormat = Type; // Go forth and back - f = _cmsGetFormatter(Type, cmsFormatterInput, CMS_PACK_FLAGS_FLOAT); - b = _cmsGetFormatter(Type, cmsFormatterOutput, CMS_PACK_FLAGS_FLOAT); + f = _cmsGetFormatter(0, Type, cmsFormatterInput, CMS_PACK_FLAGS_FLOAT); + b = _cmsGetFormatter(0, Type, cmsFormatterOutput, CMS_PACK_FLAGS_FLOAT); if (f.FmtFloat == NULL || b.FmtFloat == NULL) { Fail("no formatter for %s", Text); FormatterFailed = TRUE; // Useful for debug - f = _cmsGetFormatter(Type, cmsFormatterInput, CMS_PACK_FLAGS_FLOAT); - b = _cmsGetFormatter(Type, cmsFormatterOutput, CMS_PACK_FLAGS_FLOAT); + f = _cmsGetFormatter(0, Type, cmsFormatterInput, CMS_PACK_FLAGS_FLOAT); + b = _cmsGetFormatter(0, Type, cmsFormatterOutput, CMS_PACK_FLAGS_FLOAT); return; } @@ -4017,8 +4109,10 @@ C( TYPE_BGRA_HALF_FLT ); C( TYPE_ABGR_HALF_FLT ); + C( TYPE_XYZ_FLT ); + - return FormatterFailed == 0 ? 1 : 0; + return FormatterFailed == 0 ? 1 : 0; } #undef C @@ -5215,7 +5309,6 @@ SubTest("Tags holding ICC viewing conditions"); if (!CheckICCViewingConditions(Pass, h)) return 0; - SubTest("VCGT tags"); if (!CheckVCGT(Pass, h)) return 0; @@ -5249,6 +5342,44 @@ } +// Thanks to Christopher James Halse Rogers for the bugfixing and providing this test +static +cmsInt32Number CheckVersionHeaderWriting(void) +{ + cmsHPROFILE h; + int index; + float test_versions[] = { + 2.3f, + 4.08f, + 4.09f, + 4.3f + }; + + for (index = 0; index < sizeof(test_versions)/sizeof(test_versions[0]); index++) { + + h = cmsCreateProfilePlaceholder(DbgThread()); + if (h == NULL) return 0; + + cmsSetProfileVersion(h, test_versions[index]); + + cmsSaveProfileToFile(h, "versions.icc"); + cmsCloseProfile(h); + + h = cmsOpenProfileFromFileTHR(DbgThread(), "versions.icc", "r"); + + // Only the first 3 digits are significant + if (fabs(cmsGetProfileVersion(h) - test_versions[index]) > 0.005) { + Fail("Version failed to round-trip: wrote %.2f, read %.2f", + test_versions[index], cmsGetProfileVersion(h)); + return 0; + } + + cmsCloseProfile(h); + remove("versions.icc"); + } + return 1; +} + // Error reporting ------------------------------------------------------------------------------------------------------- @@ -6448,7 +6579,7 @@ SubTest("Gamut check on 16 bits"); - xform = cmsCreateProofingTransformTHR(DbgThread(), hAbove, TYPE_RGB_16, hAbove, TYPE_RGB_16, hAbove, + xform = cmsCreateProofingTransformTHR(DbgThread(), hAbove, TYPE_RGB_16, hAbove, TYPE_RGB_16, hSRGB, INTENT_RELATIVE_COLORIMETRIC, INTENT_RELATIVE_COLORIMETRIC, cmsFLAGS_GAMUTCHECK); cmsCloseProfile(hSRGB); @@ -7484,6 +7615,111 @@ } +static +cmsInt32Number CheckMeta(void) +{ + char *data; + cmsHANDLE dict; + cmsHPROFILE p; + cmsUInt32Number clen; + FILE *fp; + int rc; + + /* open file */ + p = cmsOpenProfileFromFile("ibm-t61.icc", "r"); + if (p == NULL) return 0; + + /* read dictionary, but don't do anything with the value */ + //COMMENT OUT THE NEXT TWO LINES AND IT WORKS FINE!!! + dict = cmsReadTag(p, cmsSigMetaTag); + if (dict == NULL) return 0; + + /* serialize profile to memory */ + rc = cmsSaveProfileToMem(p, NULL, &clen); + if (!rc) return 0; + + data = (char*) malloc(clen); + rc = cmsSaveProfileToMem(p, data, &clen); + if (!rc) return 0; + + /* write the memory blob to a file */ + //NOTE: The crash does not happen if cmsSaveProfileToFile() is used */ + fp = fopen("new.icc", "wb"); + fwrite(data, 1, clen, fp); + fclose(fp); + free(data); + + cmsCloseProfile(p); + + /* open newly created file and read metadata */ + p = cmsOpenProfileFromFile("new.icc", "r"); + //ERROR: Bad dictionary Name/Value + //ERROR: Corrupted tag 'meta' + //test: test.c:59: main: Assertion `dict' failed. + dict = cmsReadTag(p, cmsSigMetaTag); + if (dict == NULL) return 0; + + cmsCloseProfile(p); + return 1; +} + + +// Bug on applying null transforms on floating point buffers +static +cmsInt32Number CheckFloatNULLxform(void) +{ + int i; + cmsFloat32Number in[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; + cmsFloat32Number out[10]; + + cmsHTRANSFORM xform = cmsCreateTransform(NULL, TYPE_GRAY_FLT, NULL, TYPE_GRAY_FLT, INTENT_PERCEPTUAL, cmsFLAGS_NULLTRANSFORM); + + if (xform == NULL) { + Fail("Unable to create float null transform"); + return 0; + } + + cmsDoTransform(xform, in, out, 10); + + cmsDeleteTransform(xform); + for (i=0; i < 10; i++) { + + if (!IsGoodVal("float nullxform", in[i], out[i], 0.001)) { + + return 0; + } + } + + return 1; +} + +static +cmsInt32Number CheckRemoveTag(void) +{ + cmsHPROFILE p; + cmsMLU *mlu; + int ret; + + p = cmsCreate_sRGBProfileTHR(NULL); + + /* set value */ + mlu = cmsMLUalloc (NULL, 1); + ret = cmsMLUsetASCII (mlu, "en", "US", "bar"); + if (!ret) return 0; + + ret = cmsWriteTag (p, cmsSigDeviceMfgDescTag, mlu); + if (!ret) return 0; + + cmsMLUfree (mlu); + + /* remove the tag */ + ret = cmsWriteTag (p, cmsSigDeviceMfgDescTag, NULL); + if (!ret) return 0; + + /* THIS EXPLODES */ + cmsCloseProfile(p); + return 1; +} // -------------------------------------------------------------------------------------------------- // P E R F O R M A N C E C H E C K S @@ -7513,6 +7749,9 @@ } + + + static void SpeedTest16bits(const char * Title, cmsHPROFILE hlcmsProfileIn, cmsHPROFILE hlcmsProfileOut, cmsInt32Number Intent) { @@ -7880,271 +8119,23 @@ printf("\n"); } -// ZOO checks ------------------------------------------------------------------------------------------------------------ - - -#ifdef CMS_IS_WINDOWS_ - -static char ZOOfolder[cmsMAX_PATH] = "c:\\colormaps\\"; -static char ZOOwrite[cmsMAX_PATH] = "c:\\colormaps\\write\\"; -static char ZOORawWrite[cmsMAX_PATH] = "c:\\colormaps\\rawwrite\\"; - - -// Read all tags on a profile given by its handle -static -void ReadAllTags(cmsHPROFILE h) -{ - cmsInt32Number i, n; - cmsTagSignature sig; - - n = cmsGetTagCount(h); - for (i=0; i < n; i++) { - - sig = cmsGetTagSignature(h, i); - if (cmsReadTag(h, sig) == NULL) return; - } -} - - -// Read all tags on a profile given by its handle -static -void ReadAllRAWTags(cmsHPROFILE h) -{ - cmsInt32Number i, n; - cmsTagSignature sig; - cmsInt32Number len; - - n = cmsGetTagCount(h); - for (i=0; i < n; i++) { - - sig = cmsGetTagSignature(h, i); - len = cmsReadRawTag(h, sig, NULL, 0); - } -} - - -static -void PrintInfo(cmsHPROFILE h, cmsInfoType Info) -{ - wchar_t* text; - cmsInt32Number len; - cmsContext id = DbgThread(); - - len = cmsGetProfileInfo(h, Info, "en", "US", NULL, 0); - if (len == 0) return; - - text = _cmsMalloc(id, len); - cmsGetProfileInfo(h, Info, "en", "US", text, len); - - wprintf(L"%s\n", text); - _cmsFree(id, text); -} - - -static -void PrintAllInfos(cmsHPROFILE h) -{ - PrintInfo(h, cmsInfoDescription); - PrintInfo(h, cmsInfoManufacturer); - PrintInfo(h, cmsInfoModel); - PrintInfo(h, cmsInfoCopyright); - printf("\n\n"); -} - -static -void ReadAllLUTS(cmsHPROFILE h) -{ - cmsPipeline* a; - cmsCIEXYZ Black; - - a = _cmsReadInputLUT(h, INTENT_PERCEPTUAL); - if (a) cmsPipelineFree(a); - - a = _cmsReadInputLUT(h, INTENT_RELATIVE_COLORIMETRIC); - if (a) cmsPipelineFree(a); - - a = _cmsReadInputLUT(h, INTENT_SATURATION); - if (a) cmsPipelineFree(a); - - a = _cmsReadInputLUT(h, INTENT_ABSOLUTE_COLORIMETRIC); - if (a) cmsPipelineFree(a); - - - a = _cmsReadOutputLUT(h, INTENT_PERCEPTUAL); - if (a) cmsPipelineFree(a); - - a = _cmsReadOutputLUT(h, INTENT_RELATIVE_COLORIMETRIC); - if (a) cmsPipelineFree(a); - - a = _cmsReadOutputLUT(h, INTENT_SATURATION); - if (a) cmsPipelineFree(a); - - a = _cmsReadOutputLUT(h, INTENT_ABSOLUTE_COLORIMETRIC); - if (a) cmsPipelineFree(a); - - - a = _cmsReadDevicelinkLUT(h, INTENT_PERCEPTUAL); - if (a) cmsPipelineFree(a); - - a = _cmsReadDevicelinkLUT(h, INTENT_RELATIVE_COLORIMETRIC); - if (a) cmsPipelineFree(a); - - a = _cmsReadDevicelinkLUT(h, INTENT_SATURATION); - if (a) cmsPipelineFree(a); - - a = _cmsReadDevicelinkLUT(h, INTENT_ABSOLUTE_COLORIMETRIC); - if (a) cmsPipelineFree(a); - - - cmsDetectDestinationBlackPoint(&Black, h, INTENT_PERCEPTUAL, 0); - cmsDetectDestinationBlackPoint(&Black, h, INTENT_RELATIVE_COLORIMETRIC, 0); - cmsDetectDestinationBlackPoint(&Black, h, INTENT_SATURATION, 0); - cmsDetectDestinationBlackPoint(&Black, h, INTENT_ABSOLUTE_COLORIMETRIC, 0); - cmsDetectTAC(h); -} - -// Check one specimen in the ZOO - -static -cmsInt32Number CheckSingleSpecimen(const char* Profile) -{ - char BuffSrc[256]; - char BuffDst[256]; - cmsHPROFILE h; - - sprintf(BuffSrc, "%s%s", ZOOfolder, Profile); - sprintf(BuffDst, "%s%s", ZOOwrite, Profile); - - h = cmsOpenProfileFromFile(BuffSrc, "r"); - if (h == NULL) return 0; - - printf("%s\n", Profile); - PrintAllInfos(h); - ReadAllTags(h); - // ReadAllRAWTags(h); - ReadAllLUTS(h); - - cmsSaveProfileToFile(h, BuffDst); - cmsCloseProfile(h); - - h = cmsOpenProfileFromFile(BuffDst, "r"); - if (h == NULL) return 0; - ReadAllTags(h); - - - cmsCloseProfile(h); - - return 1; -} - -static -cmsInt32Number CheckRAWSpecimen(const char* Profile) -{ - char BuffSrc[256]; - char BuffDst[256]; - cmsHPROFILE h; - - sprintf(BuffSrc, "%s%s", ZOOfolder, Profile); - sprintf(BuffDst, "%s%s", ZOORawWrite, Profile); - - h = cmsOpenProfileFromFile(BuffSrc, "r"); - if (h == NULL) return 0; - - ReadAllTags(h); - ReadAllRAWTags(h); - cmsSaveProfileToFile(h, BuffDst); - cmsCloseProfile(h); - - h = cmsOpenProfileFromFile(BuffDst, "r"); - if (h == NULL) return 0; - ReadAllTags(h); - cmsCloseProfile(h); - - return 1; -} - - -static -void CheckProfileZOO(void) -{ - - struct _finddata_t c_file; - intptr_t hFile; - - cmsSetLogErrorHandler(NULL); - - if ( (hFile = _findfirst("c:\\colormaps\\*.*", &c_file)) == -1L ) - printf("No files in current directory"); - else - { - do - { - - printf("%s\n", c_file.name); - if (strcmp(c_file.name, ".") != 0 && - strcmp(c_file.name, "..") != 0) { - - CheckSingleSpecimen( c_file.name); - CheckRAWSpecimen( c_file.name); - - if (TotalMemory > 0) - printf("Ok, but %s are left!\n", MemStr(TotalMemory)); - else - printf("Ok.\n"); - - } - - } while ( _findnext(hFile, &c_file) == 0 ); - - _findclose(hFile); - } - - cmsSetLogErrorHandler(FatalErrorQuit); -} - -#endif - - -#if 0 -#define TYPE_709 709 -static double Rec709Math(int Type, const double Params[], double R) -{ double Fun; - -switch (Type) -{ -case 709: - -if (R <= (Params[3]*Params[4])) Fun = R / Params[3]; -else Fun = pow(((R - Params[2])/Params[1]), Params[0]); -break; -case -709: -if (R <= Params[4]) Fun = R * Params[3]; -else Fun = Params[1] * pow(R, (1/Params[0])) + Params[2]; -break; -} -return Fun; -} +// --------------------------------------------------------------------------------------- -// Add nonstandard TRC curves -> Rec709 -cmsPluginParametricCurves NewCurvePlugin = { -{ cmsPluginMagicNumber, 2000, cmsPluginParametricCurveSig, NULL }, -1, {TYPE_709}, {5}, Rec709Math}; +#ifdef LCMS_FAST_EXTENSIONS + void* cmsFast8Bitextensions(void); #endif - - - -// --------------------------------------------------------------------------------------- - int main(int argc, char* argv[]) { cmsInt32Number Exhaustive = 0; cmsInt32Number DoSpeedTests = 1; cmsInt32Number DoCheckTests = 1; + cmsInt32Number DoPluginTests = 1; + cmsInt32Number DoZooTests = 0; #ifdef _MSC_VER _CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF ); @@ -8158,6 +8149,12 @@ printf("Running exhaustive tests (will take a while...)\n\n"); } +#ifdef LCMS_FAST_EXTENSIONS + printf("Installing fast 8 bit extension ..."); + cmsPlugin(cmsFast8Bitextensions()); + printf("done.\n"); +#endif + printf("Installing debug memory plug-in ... "); cmsPlugin(&DebugMemHandler); printf("done.\n"); @@ -8166,26 +8163,23 @@ cmsSetLogErrorHandler(FatalErrorQuit); printf("done.\n"); -#ifdef CMS_IS_WINDOWS_ - // CheckProfileZOO(); -#endif PrintSupportedIntents(); - - - // Create utility profiles - Check("Creation of test profiles", CreateTestProfiles); - - if (DoCheckTests) - { Check("Base types", CheckBaseTypes); Check("endianess", CheckEndianess); Check("quick floor", CheckQuickFloor); Check("quick floor word", CheckQuickFloorWord); Check("Fixed point 15.16 representation", CheckFixedPoint15_16); Check("Fixed point 8.8 representation", CheckFixedPoint8_8); + Check("D50 roundtrip", CheckD50Roundtrip); + + // Create utility profiles + if (DoCheckTests || DoSpeedTests) + Check("Creation of test profiles", CreateTestProfiles); + if (DoCheckTests) { + // Forward 1D interpolation Check("1D interpolation in 2pt tables", Check1DLERP2); Check("1D interpolation in 3pt tables", Check1DLERP3); @@ -8303,7 +8297,7 @@ // Profile I/O (this one is huge!) Check("Profile creation", CheckProfileCreation); - + Check("Header version", CheckVersionHeaderWriting); // Error reporting Check("Error reporting on bad profiles", CheckErrReportingOnBadProfiles); @@ -8358,18 +8352,45 @@ Check("Floating Point sampled curve with non-zero start", CheckFloatSamples); Check("Floating Point segmented curve with short sampled segement", CheckFloatSegments); Check("Read RAW portions", CheckReadRAW); + Check("Check MetaTag", CheckMeta); + Check("Null transform on floats", CheckFloatNULLxform); + Check("Set free a tag", CheckRemoveTag); + } + + if (DoPluginTests) + { +#ifndef CMS_CONTEXT_IN_LEGACY_MODE + Check("Context memory handling", CheckAllocContext); + Check("Simple context functionality", CheckSimpleContext); + Check("Alarm codes context", CheckAlarmColorsContext); + Check("Adaptation state context", CheckAdaptationStateContext); + Check("1D interpolation plugin", CheckInterp1DPlugin); + Check("3D interpolation plugin", CheckInterp3DPlugin); + Check("Parametric curve plugin", CheckParametricCurvePlugin); + Check("Formatters plugin", CheckFormattersPlugin); + Check("Tag type plugin", CheckTagTypePlugin); + Check("MPE type plugin", CheckMPEPlugin); + Check("Optimization plugin", CheckOptimizationPlugin); + Check("Rendering intent plugin", CheckIntentPlugin); + Check("Full transform plugin", CheckTransformPlugin); + Check("Mutex plugin", CheckMutexPlugin); +#endif } if (DoSpeedTests) SpeedTest(); + if (DoZooTests) + CheckProfileZOO(); + DebugMemPrintTotals(); cmsUnregisterPlugins(); // Cleanup - RemoveTestProfiles(); + if (DoCheckTests || DoSpeedTests) + RemoveTestProfiles(); return TotalFail; } diff -Nru lcms2-2.5/testbed/testcms2.h lcms2-2.6/testbed/testcms2.h --- lcms2-2.5/testbed/testcms2.h 1970-01-01 00:00:00.000000000 +0000 +++ lcms2-2.6/testbed/testcms2.h 2014-03-17 16:09:30.000000000 +0000 @@ -0,0 +1,84 @@ +//--------------------------------------------------------------------------------- +// +// Little Color Management System +// Copyright (c) 1998-2014 Marti Maria Saguer +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the "Software"), +// to deal in the Software without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Software, and to permit persons to whom the Software +// is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO +// THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +//--------------------------------------------------------------------------------- +// + +#ifndef TESTCMS2_H +#define TESTCMS2_H + +#ifdef _MSC_VER +# define _CRT_SECURE_NO_WARNINGS 1 +# include "crtdbg.h" +# include +#endif + +#include "lcms2_internal.h" + +#define cmsmin(a, b) (((a) < (b)) ? (a) : (b)) + +// Used to mark special pointers +void DebugMemDontCheckThis(void *Ptr); + + +cmsBool IsGoodVal(const char *title, cmsFloat64Number in, cmsFloat64Number out, cmsFloat64Number max); +cmsBool IsGoodFixed15_16(const char *title, cmsFloat64Number in, cmsFloat64Number out); +cmsBool IsGoodFixed8_8(const char *title, cmsFloat64Number in, cmsFloat64Number out); +cmsBool IsGoodWord(const char *title, cmsUInt16Number in, cmsUInt16Number out); +cmsBool IsGoodWordPrec(const char *title, cmsUInt16Number in, cmsUInt16Number out, cmsUInt16Number maxErr); + +void* PluginMemHandler(void); +cmsContext WatchDogContext(void* usr); + +void ResetFatalError(void); +void Die(const char* Reason); +void Dot(void); +void Fail(const char* frm, ...); +void SubTest(const char* frm, ...); +void TestMemoryLeaks(cmsBool ok); +void Say(const char* str); + +// Plug-in tests +cmsInt32Number CheckSimpleContext(void); +cmsInt32Number CheckAllocContext(void); +cmsInt32Number CheckAlarmColorsContext(void); +cmsInt32Number CheckAdaptationStateContext(void); +cmsInt32Number CheckInterp1DPlugin(void); +cmsInt32Number CheckInterp3DPlugin(void); +cmsInt32Number CheckParametricCurvePlugin(void); +cmsInt32Number CheckFormattersPlugin(void); +cmsInt32Number CheckTagTypePlugin(void); +cmsInt32Number CheckMPEPlugin(void); +cmsInt32Number CheckOptimizationPlugin(void); +cmsInt32Number CheckIntentPlugin(void); +cmsInt32Number CheckTransformPlugin(void); +cmsInt32Number CheckMutexPlugin(void); + + +cmsInt32Number CheckOptimizationPluginLeak(void); + +// Zoo +void CheckProfileZOO(void); + +#endif + diff -Nru lcms2-2.5/testbed/testplugin.c lcms2-2.6/testbed/testplugin.c --- lcms2-2.5/testbed/testplugin.c 1970-01-01 00:00:00.000000000 +0000 +++ lcms2-2.6/testbed/testplugin.c 2014-03-17 16:09:30.000000000 +0000 @@ -0,0 +1,1476 @@ +//--------------------------------------------------------------------------------- +// +// Little Color Management System +// Copyright (c) 1998-2014 Marti Maria Saguer +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the "Software"), +// to deal in the Software without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Software, and to permit persons to whom the Software +// is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO +// THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +//--------------------------------------------------------------------------------- +// + +#include "testcms2.h" + +// -------------------------------------------------------------------------------------------------- +// Auxiliar, duplicate a context and mark the block as non-debug because in this case the allocator +// and deallocator have different context owners +// -------------------------------------------------------------------------------------------------- + +static +cmsContext DupContext(cmsContext src, void* Data) +{ + cmsContext cpy = cmsDupContext(src, Data); + + DebugMemDontCheckThis(cpy); + + return cpy; +} + +// -------------------------------------------------------------------------------------------------- +// Simple context functions +// -------------------------------------------------------------------------------------------------- + +// Allocation order +cmsInt32Number CheckAllocContext(void) +{ + cmsContext c1, c2, c3, c4; + + + c1 = cmsCreateContext(NULL, NULL); // This creates a context by using the normal malloc + DebugMemDontCheckThis(c1); + cmsDeleteContext(c1); + + c2 = cmsCreateContext(PluginMemHandler(), NULL); // This creates a context by using the debug malloc + DebugMemDontCheckThis(c2); + cmsDeleteContext(c2); + + c1 = cmsCreateContext(NULL, NULL); + DebugMemDontCheckThis(c1); + + c2 = cmsCreateContext(PluginMemHandler(), NULL); + DebugMemDontCheckThis(c2); + + cmsPluginTHR(c1, PluginMemHandler()); // Now the context have custom allocators + + c3 = DupContext(c1, NULL); + c4 = DupContext(c2, NULL); + + + + cmsDeleteContext(c1); // Should be deleted by using nomal malloc + cmsDeleteContext(c2); // Should be deleted by using debug malloc + cmsDeleteContext(c3); // Should be deleted by using nomal malloc + cmsDeleteContext(c4); // Should be deleted by using debug malloc + + return 1; +} + +// Test the very basic context capabilities +cmsInt32Number CheckSimpleContext(void) +{ + int a = 1; + int b = 32; + cmsInt32Number rc = 0; + + cmsContext c1, c2, c3; + + // This function creates a context with a special + // memory manager that check allocation + c1 = WatchDogContext(&a); + cmsDeleteContext(c1); + + c1 = WatchDogContext(&a); + + // Let's check duplication + c2 = DupContext(c1, NULL); + c3 = DupContext(c2, NULL); + + // User data should have been propagated + rc = (*(int*) cmsGetContextUserData(c3)) == 1 ; + + // Free resources + cmsDeleteContext(c1); + cmsDeleteContext(c2); + cmsDeleteContext(c3); + + if (!rc) { + Fail("Creation of user data failed"); + return 0; + } + + // Back to create 3 levels of inherance + c1 = cmsCreateContext(NULL, &a); + DebugMemDontCheckThis(c1); + + c2 = DupContext(c1, NULL); + c3 = DupContext(c2, &b); + + rc = (*(int*) cmsGetContextUserData(c3)) == 32 ; + + cmsDeleteContext(c1); + cmsDeleteContext(c2); + cmsDeleteContext(c3); + + if (!rc) { + Fail("Modification of user data failed"); + return 0; + } + + // All seems ok + return rc; +} + + + + +// -------------------------------------------------------------------------------------------------- +//Alarm color functions +// -------------------------------------------------------------------------------------------------- + +// This function tests the alarm codes across contexts +cmsInt32Number CheckAlarmColorsContext(void) +{ + cmsInt32Number rc = 0; + const cmsUInt16Number codes[] = {0x0000, 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0x6666, 0x7777, 0x8888, 0x9999, 0xaaaa, 0xbbbb, 0xcccc, 0xdddd, 0xeeee, 0xffff}; + cmsUInt16Number out[16]; + cmsContext c1, c2, c3; + int i; + + c1 = WatchDogContext(NULL); + + cmsSetAlarmCodesTHR(c1, codes); + c2 = DupContext(c1, NULL); + c3 = DupContext(c2, NULL); + + cmsGetAlarmCodesTHR(c3, out); + + rc = 1; + for (i=0; i < 16; i++) { + if (out[i] != codes[i]) { + Fail("Bad alarm code %x != %x", out[i], codes[i]); + rc = 0; + break; + } + } + + cmsDeleteContext(c1); + cmsDeleteContext(c2); + cmsDeleteContext(c3); + + return rc; +} + + +// -------------------------------------------------------------------------------------------------- +//Adaptation state functions +// -------------------------------------------------------------------------------------------------- + +// Similar to the previous, but for adaptation state +cmsInt32Number CheckAdaptationStateContext(void) +{ + cmsInt32Number rc = 0; + cmsContext c1, c2, c3; + cmsFloat64Number old1, old2; + + old1 = cmsSetAdaptationStateTHR(NULL, -1); + + c1 = WatchDogContext(NULL); + + cmsSetAdaptationStateTHR(c1, 0.7); + + c2 = DupContext(c1, NULL); + c3 = DupContext(c2, NULL); + + rc = IsGoodVal("Adaptation state", cmsSetAdaptationStateTHR(c3, -1), 0.7, 0.001); + + cmsDeleteContext(c1); + cmsDeleteContext(c2); + cmsDeleteContext(c3); + + old2 = cmsSetAdaptationStateTHR(NULL, -1); + + if (old1 != old2) { + Fail("Adaptation state has changed"); + return 0; + } + + return rc; +} + +// -------------------------------------------------------------------------------------------------- +// Interpolation plugin check: A fake 1D and 3D interpolation will be used to test the functionality. +// -------------------------------------------------------------------------------------------------- + +// This fake interpolation takes always the closest lower node in the interpolation table for 1D +static +void Fake1Dfloat(const cmsFloat32Number Value[], + cmsFloat32Number Output[], + const cmsInterpParams* p) +{ + cmsFloat32Number val2; + int cell; + const cmsFloat32Number* LutTable = (const cmsFloat32Number*) p ->Table; + + // Clip upper values + if (Value[0] >= 1.0) { + Output[0] = LutTable[p -> Domain[0]]; + return; + } + + val2 = p -> Domain[0] * Value[0]; + cell = (int) floor(val2); + Output[0] = LutTable[cell] ; +} + +// This fake interpolation just uses scrambled negated indexes for output +static +void Fake3D16(register const cmsUInt16Number Input[], + register cmsUInt16Number Output[], + register const struct _cms_interp_struc* p) +{ + Output[0] = 0xFFFF - Input[2]; + Output[1] = 0xFFFF - Input[1]; + Output[2] = 0xFFFF - Input[0]; +} + +// The factory chooses interpolation routines on depending on certain conditions. +cmsInterpFunction my_Interpolators_Factory(cmsUInt32Number nInputChannels, + cmsUInt32Number nOutputChannels, + cmsUInt32Number dwFlags) +{ + cmsInterpFunction Interpolation; + cmsBool IsFloat = (dwFlags & CMS_LERP_FLAGS_FLOAT); + + // Initialize the return to zero as a non-supported mark + memset(&Interpolation, 0, sizeof(Interpolation)); + + // For 1D to 1D and floating point + if (nInputChannels == 1 && nOutputChannels == 1 && IsFloat) { + + Interpolation.LerpFloat = Fake1Dfloat; + } + else + if (nInputChannels == 3 && nOutputChannels == 3 && !IsFloat) { + + // For 3D to 3D and 16 bits + Interpolation.Lerp16 = Fake3D16; + } + + // Here is the interpolation + return Interpolation; +} + +// Interpolation plug-in +static +cmsPluginInterpolation InterpPluginSample = { + + { cmsPluginMagicNumber, 2060, cmsPluginInterpolationSig, NULL }, + my_Interpolators_Factory +}; + + +// This is the check code for 1D interpolation plug-in +cmsInt32Number CheckInterp1DPlugin(void) +{ + cmsToneCurve* Sampled1D = NULL; + cmsContext ctx = NULL; + cmsContext cpy = NULL; + const cmsFloat32Number tab[] = { 0.0f, 0.10f, 0.20f, 0.30f, 0.40f, 0.50f, 0.60f, 0.70f, 0.80f, 0.90f, 1.00f }; // A straight line + + // 1st level context + ctx = WatchDogContext(NULL); + if (ctx == NULL) { + Fail("Cannot create context"); + goto Error; + } + + cmsPluginTHR(ctx, &InterpPluginSample); + + cpy = DupContext(ctx, NULL); + if (cpy == NULL) { + Fail("Cannot create context (2)"); + goto Error; + } + + Sampled1D = cmsBuildTabulatedToneCurveFloat(cpy, 11, tab); + if (Sampled1D == NULL) { + Fail("Cannot create tone curve (1)"); + goto Error; + } + + // Do some interpolations with the plugin + if (!IsGoodVal("0.10", cmsEvalToneCurveFloat(Sampled1D, 0.10f), 0.10, 0.01)) goto Error; + if (!IsGoodVal("0.13", cmsEvalToneCurveFloat(Sampled1D, 0.13f), 0.10, 0.01)) goto Error; + if (!IsGoodVal("0.55", cmsEvalToneCurveFloat(Sampled1D, 0.55f), 0.50, 0.01)) goto Error; + if (!IsGoodVal("0.9999", cmsEvalToneCurveFloat(Sampled1D, 0.9999f), 0.90, 0.01)) goto Error; + + cmsFreeToneCurve(Sampled1D); + cmsDeleteContext(ctx); + cmsDeleteContext(cpy); + + // Now in global context + Sampled1D = cmsBuildTabulatedToneCurveFloat(NULL, 11, tab); + if (Sampled1D == NULL) { + Fail("Cannot create tone curve (2)"); + goto Error; + } + + // Now without the plug-in + if (!IsGoodVal("0.10", cmsEvalToneCurveFloat(Sampled1D, 0.10f), 0.10, 0.001)) goto Error; + if (!IsGoodVal("0.13", cmsEvalToneCurveFloat(Sampled1D, 0.13f), 0.13, 0.001)) goto Error; + if (!IsGoodVal("0.55", cmsEvalToneCurveFloat(Sampled1D, 0.55f), 0.55, 0.001)) goto Error; + if (!IsGoodVal("0.9999", cmsEvalToneCurveFloat(Sampled1D, 0.9999f), 0.9999, 0.001)) goto Error; + + cmsFreeToneCurve(Sampled1D); + return 1; + +Error: + if (ctx != NULL) cmsDeleteContext(ctx); + if (cpy != NULL) cmsDeleteContext(ctx); + if (Sampled1D != NULL) cmsFreeToneCurve(Sampled1D); + return 0; + +} + +// Checks the 3D interpolation +cmsInt32Number CheckInterp3DPlugin(void) +{ + + cmsPipeline* p; + cmsStage* clut; + cmsContext ctx; + cmsUInt16Number In[3], Out[3]; + cmsUInt16Number identity[] = { + + 0, 0, 0, + 0, 0, 0xffff, + 0, 0xffff, 0, + 0, 0xffff, 0xffff, + 0xffff, 0, 0, + 0xffff, 0, 0xffff, + 0xffff, 0xffff, 0, + 0xffff, 0xffff, 0xffff + }; + + + ctx = WatchDogContext(NULL); + if (ctx == NULL) { + Fail("Cannot create context"); + return 0; + } + + + cmsPluginTHR(ctx, &InterpPluginSample); + + + p = cmsPipelineAlloc(ctx, 3, 3); + clut = cmsStageAllocCLut16bit(ctx, 2, 3, 3, identity); + cmsPipelineInsertStage(p, cmsAT_BEGIN, clut); + + // Do some interpolations with the plugin + + In[0] = 0; In[1] = 0; In[2] = 0; + cmsPipelineEval16(In, Out, p); + + if (!IsGoodWord("0", Out[0], 0xFFFF - 0)) goto Error; + if (!IsGoodWord("1", Out[1], 0xFFFF - 0)) goto Error; + if (!IsGoodWord("2", Out[2], 0xFFFF - 0)) goto Error; + + In[0] = 0x1234; In[1] = 0x5678; In[2] = 0x9ABC; + cmsPipelineEval16(In, Out, p); + + if (!IsGoodWord("0", 0xFFFF - 0x9ABC, Out[0])) goto Error; + if (!IsGoodWord("1", 0xFFFF - 0x5678, Out[1])) goto Error; + if (!IsGoodWord("2", 0xFFFF - 0x1234, Out[2])) goto Error; + + cmsPipelineFree(p); + cmsDeleteContext(ctx); + + // Now without the plug-in + + p = cmsPipelineAlloc(NULL, 3, 3); + clut = cmsStageAllocCLut16bit(NULL, 2, 3, 3, identity); + cmsPipelineInsertStage(p, cmsAT_BEGIN, clut); + + In[0] = 0; In[1] = 0; In[2] = 0; + cmsPipelineEval16(In, Out, p); + + if (!IsGoodWord("0", 0, Out[0])) goto Error; + if (!IsGoodWord("1", 0, Out[1])) goto Error; + if (!IsGoodWord("2", 0, Out[2])) goto Error; + + In[0] = 0x1234; In[1] = 0x5678; In[2] = 0x9ABC; + cmsPipelineEval16(In, Out, p); + + if (!IsGoodWord("0", 0x1234, Out[0])) goto Error; + if (!IsGoodWord("1", 0x5678, Out[1])) goto Error; + if (!IsGoodWord("2", 0x9ABC, Out[2])) goto Error; + + cmsPipelineFree(p); + return 1; + +Error: + cmsPipelineFree(p); + return 0; + +} + +// -------------------------------------------------------------------------------------------------- +// Parametric curve plugin check: sin(x)/cos(x) function will be used to test the functionality. +// -------------------------------------------------------------------------------------------------- + +#define TYPE_SIN 1000 +#define TYPE_COS 1010 +#define TYPE_TAN 1020 +#define TYPE_709 709 + +static cmsFloat64Number my_fns(cmsInt32Number Type, + const cmsFloat64Number Params[], + cmsFloat64Number R) +{ + cmsFloat64Number Val; + switch (Type) { + + case TYPE_SIN: + Val = Params[0]* sin(R * M_PI); + break; + + case -TYPE_SIN: + Val = asin(R) / (M_PI * Params[0]); + break; + + case TYPE_COS: + Val = Params[0]* cos(R * M_PI); + break; + + case -TYPE_COS: + Val = acos(R) / (M_PI * Params[0]); + break; + + default: return -1.0; + + } + + return Val; +} + +static +cmsFloat64Number my_fns2(cmsInt32Number Type, + const cmsFloat64Number Params[], + cmsFloat64Number R) +{ + cmsFloat64Number Val; + switch (Type) { + + case TYPE_TAN: + Val = Params[0]* tan(R * M_PI); + break; + + case -TYPE_TAN: + Val = atan(R) / (M_PI * Params[0]); + break; + + default: return -1.0; + } + + return Val; +} + + +static double Rec709Math(int Type, const double Params[], double R) +{ + double Fun; + + switch (Type) + { + case 709: + + if (R <= (Params[3]*Params[4])) Fun = R / Params[3]; + else Fun = pow(((R - Params[2])/Params[1]), Params[0]); + break; + + case -709: + + if (R <= Params[4]) Fun = R * Params[3]; + else Fun = Params[1] * pow(R, (1/Params[0])) + Params[2]; + break; + } + return Fun; +} + + +// Add nonstandard TRC curves -> Rec709 + +cmsPluginParametricCurves Rec709Plugin = { + + { cmsPluginMagicNumber, 2060, cmsPluginParametricCurveSig, NULL }, + + 1, {TYPE_709}, {5}, Rec709Math + +}; + + +static +cmsPluginParametricCurves CurvePluginSample = { + { cmsPluginMagicNumber, 2060, cmsPluginParametricCurveSig, NULL }, + + 2, // nFunctions + { TYPE_SIN, TYPE_COS }, // Function Types + { 1, 1 }, // ParameterCount + my_fns // Evaluator +}; + +static +cmsPluginParametricCurves CurvePluginSample2 = { + { cmsPluginMagicNumber, 2060, cmsPluginParametricCurveSig, NULL }, + + 1, // nFunctions + { TYPE_TAN}, // Function Types + { 1 }, // ParameterCount + my_fns2 // Evaluator +}; + +// -------------------------------------------------------------------------------------------------- +// In this test, the DupContext function will be checked as well +// -------------------------------------------------------------------------------------------------- +cmsInt32Number CheckParametricCurvePlugin(void) +{ + cmsContext ctx = NULL; + cmsContext cpy = NULL; + cmsContext cpy2 = NULL; + cmsToneCurve* sinus; + cmsToneCurve* cosinus; + cmsToneCurve* tangent; + cmsToneCurve* reverse_sinus; + cmsToneCurve* reverse_cosinus; + cmsFloat64Number scale = 1.0; + + + ctx = WatchDogContext(NULL); + + cmsPluginTHR(ctx, &CurvePluginSample); + + cpy = DupContext(ctx, NULL); + + cmsPluginTHR(cpy, &CurvePluginSample2); + + cpy2 = DupContext(cpy, NULL); + + cmsPluginTHR(cpy2, &Rec709Plugin); + + + sinus = cmsBuildParametricToneCurve(cpy, TYPE_SIN, &scale); + cosinus = cmsBuildParametricToneCurve(cpy, TYPE_COS, &scale); + tangent = cmsBuildParametricToneCurve(cpy, TYPE_TAN, &scale); + reverse_sinus = cmsReverseToneCurve(sinus); + reverse_cosinus = cmsReverseToneCurve(cosinus); + + + if (!IsGoodVal("0.10", cmsEvalToneCurveFloat(sinus, 0.10f), sin(0.10 * M_PI) , 0.001)) goto Error; + if (!IsGoodVal("0.60", cmsEvalToneCurveFloat(sinus, 0.60f), sin(0.60* M_PI), 0.001)) goto Error; + if (!IsGoodVal("0.90", cmsEvalToneCurveFloat(sinus, 0.90f), sin(0.90* M_PI), 0.001)) goto Error; + + if (!IsGoodVal("0.10", cmsEvalToneCurveFloat(cosinus, 0.10f), cos(0.10* M_PI), 0.001)) goto Error; + if (!IsGoodVal("0.60", cmsEvalToneCurveFloat(cosinus, 0.60f), cos(0.60* M_PI), 0.001)) goto Error; + if (!IsGoodVal("0.90", cmsEvalToneCurveFloat(cosinus, 0.90f), cos(0.90* M_PI), 0.001)) goto Error; + + if (!IsGoodVal("0.10", cmsEvalToneCurveFloat(tangent, 0.10f), tan(0.10* M_PI), 0.001)) goto Error; + if (!IsGoodVal("0.60", cmsEvalToneCurveFloat(tangent, 0.60f), tan(0.60* M_PI), 0.001)) goto Error; + if (!IsGoodVal("0.90", cmsEvalToneCurveFloat(tangent, 0.90f), tan(0.90* M_PI), 0.001)) goto Error; + + + if (!IsGoodVal("0.10", cmsEvalToneCurveFloat(reverse_sinus, 0.10f), asin(0.10)/M_PI, 0.001)) goto Error; + if (!IsGoodVal("0.60", cmsEvalToneCurveFloat(reverse_sinus, 0.60f), asin(0.60)/M_PI, 0.001)) goto Error; + if (!IsGoodVal("0.90", cmsEvalToneCurveFloat(reverse_sinus, 0.90f), asin(0.90)/M_PI, 0.001)) goto Error; + + if (!IsGoodVal("0.10", cmsEvalToneCurveFloat(reverse_cosinus, 0.10f), acos(0.10)/M_PI, 0.001)) goto Error; + if (!IsGoodVal("0.60", cmsEvalToneCurveFloat(reverse_cosinus, 0.60f), acos(0.60)/M_PI, 0.001)) goto Error; + if (!IsGoodVal("0.90", cmsEvalToneCurveFloat(reverse_cosinus, 0.90f), acos(0.90)/M_PI, 0.001)) goto Error; + + cmsFreeToneCurve(sinus); + cmsFreeToneCurve(cosinus); + cmsFreeToneCurve(tangent); + cmsFreeToneCurve(reverse_sinus); + cmsFreeToneCurve(reverse_cosinus); + + cmsDeleteContext(ctx); + cmsDeleteContext(cpy); + cmsDeleteContext(cpy2); + + return 1; + +Error: + + cmsFreeToneCurve(sinus); + cmsFreeToneCurve(reverse_sinus); + cmsFreeToneCurve(cosinus); + cmsFreeToneCurve(reverse_cosinus); + + if (ctx != NULL) cmsDeleteContext(ctx); + if (cpy != NULL) cmsDeleteContext(cpy); + if (cpy2 != NULL) cmsDeleteContext(cpy2); + return 0; +} + +// -------------------------------------------------------------------------------------------------- +// formatters plugin check: 5-6-5 RGB format +// -------------------------------------------------------------------------------------------------- + +// We define this special type as 0 bytes not float, and set the upper bit + +#define TYPE_RGB_565 (COLORSPACE_SH(PT_RGB)|CHANNELS_SH(3)|BYTES_SH(0) | (1 << 23)) + +cmsUInt8Number* my_Unroll565(register struct _cmstransform_struct* nfo, + register cmsUInt16Number wIn[], + register cmsUInt8Number* accum, + register cmsUInt32Number Stride) +{ + cmsUInt16Number pixel = *(cmsUInt16Number*) accum; // Take whole pixel + + double r = floor(((double) (pixel & 31) * 65535.0) / 31.0 + 0.5); + double g = floor((((pixel >> 5) & 63) * 65535.0) / 63.0 + 0.5); + double b = floor((((pixel >> 11) & 31) * 65535.0) / 31.0 + 0.5); + + wIn[2] = (cmsUInt16Number) r; + wIn[1] = (cmsUInt16Number) g; + wIn[0] = (cmsUInt16Number) b; + + return accum + 2; +} + +cmsUInt8Number* my_Pack565(register _cmsTRANSFORM* info, + register cmsUInt16Number wOut[], + register cmsUInt8Number* output, + register cmsUInt32Number Stride) +{ + + register cmsUInt16Number pixel; + int r, g, b; + + r = (int) floor(( wOut[2] * 31) / 65535.0 + 0.5); + g = (int) floor(( wOut[1] * 63) / 65535.0 + 0.5); + b = (int) floor(( wOut[0] * 31) / 65535.0 + 0.5); + + + pixel = (r & 31) | (( g & 63) << 5) | ((b & 31) << 11); + + + *(cmsUInt16Number*) output = pixel; + return output + 2; +} + + +cmsFormatter my_FormatterFactory(cmsUInt32Number Type, + cmsFormatterDirection Dir, + cmsUInt32Number dwFlags) +{ + cmsFormatter Result = { NULL }; + + if ((Type == TYPE_RGB_565) && + !(dwFlags & CMS_PACK_FLAGS_FLOAT) && + (Dir == cmsFormatterInput)) { + Result.Fmt16 = my_Unroll565; + } + return Result; +} + + +cmsFormatter my_FormatterFactory2(cmsUInt32Number Type, + cmsFormatterDirection Dir, + cmsUInt32Number dwFlags) +{ + cmsFormatter Result = { NULL }; + + if ((Type == TYPE_RGB_565) && + !(dwFlags & CMS_PACK_FLAGS_FLOAT) && + (Dir == cmsFormatterOutput)) { + Result.Fmt16 = my_Pack565; + } + return Result; +} + +static +cmsPluginFormatters FormattersPluginSample = { {cmsPluginMagicNumber, + 2060, + cmsPluginFormattersSig, + NULL}, + my_FormatterFactory }; + + + +static +cmsPluginFormatters FormattersPluginSample2 = { {cmsPluginMagicNumber, + 2060, + cmsPluginFormattersSig, + NULL}, + my_FormatterFactory2 }; + + +cmsInt32Number CheckFormattersPlugin(void) +{ + cmsContext ctx = WatchDogContext(NULL); + cmsContext cpy; + cmsContext cpy2; + cmsHTRANSFORM xform; + cmsUInt16Number stream[]= { 0xffffU, 0x1234U, 0x0000U, 0x33ddU }; + cmsUInt16Number result[4]; + int i; + + + cmsPluginTHR(ctx, &FormattersPluginSample); + + cpy = DupContext(ctx, NULL); + + cmsPluginTHR(cpy, &FormattersPluginSample2); + + cpy2 = DupContext(cpy, NULL); + + xform = cmsCreateTransformTHR(cpy2, NULL, TYPE_RGB_565, NULL, TYPE_RGB_565, INTENT_PERCEPTUAL, cmsFLAGS_NULLTRANSFORM); + + cmsDoTransform(xform, stream, result, 4); + + cmsDeleteTransform(xform); + cmsDeleteContext(ctx); + cmsDeleteContext(cpy); + cmsDeleteContext(cpy2); + + for (i=0; i < 4; i++) + if (stream[i] != result[i]) return 0; + + return 1; +} + +// -------------------------------------------------------------------------------------------------- +// TagTypePlugin plugin check +// -------------------------------------------------------------------------------------------------- + +#define SigIntType ((cmsTagTypeSignature) 0x74747448) // 'tttH' +#define SigInt ((cmsTagSignature) 0x74747448) // 'tttH' + +static +void *Type_int_Read(struct _cms_typehandler_struct* self, + cmsIOHANDLER* io, + cmsUInt32Number* nItems, + cmsUInt32Number SizeOfTag) +{ + cmsUInt32Number* Ptr = (cmsUInt32Number*) _cmsMalloc(self ->ContextID, sizeof(cmsUInt32Number)); + if (Ptr == NULL) return NULL; + if (!_cmsReadUInt32Number(io, Ptr)) return NULL; + *nItems = 1; + return Ptr; +} + +static +cmsBool Type_int_Write(struct _cms_typehandler_struct* self, + cmsIOHANDLER* io, + void* Ptr, cmsUInt32Number nItems) +{ + return _cmsWriteUInt32Number(io, *(cmsUInt32Number*) Ptr); +} + +static +void* Type_int_Dup(struct _cms_typehandler_struct* self, + const void *Ptr, cmsUInt32Number n) +{ + return _cmsDupMem(self ->ContextID, Ptr, n * sizeof(cmsUInt32Number)); +} + +void Type_int_Free(struct _cms_typehandler_struct* self, + void* Ptr) +{ + _cmsFree(self ->ContextID, Ptr); +} + + +static cmsPluginTag HiddenTagPluginSample = { + + { cmsPluginMagicNumber, 2060, cmsPluginTagSig, NULL}, + SigInt, { 1, 1, { SigIntType }, NULL } +}; + +static cmsPluginTagType TagTypePluginSample = { + + { cmsPluginMagicNumber, 2060, cmsPluginTagTypeSig, (cmsPluginBase*) &HiddenTagPluginSample}, + { SigIntType, Type_int_Read, Type_int_Write, Type_int_Dup, Type_int_Free, NULL } +}; + + +cmsInt32Number CheckTagTypePlugin(void) +{ + cmsContext ctx = NULL; + cmsContext cpy = NULL; + cmsContext cpy2 = NULL; + cmsHPROFILE h = NULL; + cmsUInt32Number myTag = 1234; + cmsUInt32Number rc = 0; + char* data = NULL; + cmsUInt32Number *ptr = NULL; + cmsUInt32Number clen = 0; + + + ctx = WatchDogContext(NULL); + cmsPluginTHR(ctx, &TagTypePluginSample); + + cpy = DupContext(ctx, NULL); + cpy2 = DupContext(cpy, NULL); + + cmsDeleteContext(ctx); + cmsDeleteContext(cpy); + + h = cmsCreateProfilePlaceholder(cpy2); + if (h == NULL) { + Fail("Create placeholder failed"); + goto Error; + } + + + if (!cmsWriteTag(h, SigInt, &myTag)) { + Fail("Plug-in failed"); + goto Error; + } + + rc = cmsSaveProfileToMem(h, NULL, &clen); + if (!rc) { + Fail("Fetch mem size failed"); + goto Error; + } + + + data = (char*) malloc(clen); + if (data == NULL) { + Fail("malloc failed ?!?"); + goto Error; + } + + + rc = cmsSaveProfileToMem(h, data, &clen); + if (!rc) { + Fail("Save to mem failed"); + goto Error; + } + + cmsCloseProfile(h); + + cmsSetLogErrorHandler(NULL); + h = cmsOpenProfileFromMem(data, clen); + if (h == NULL) { + Fail("Open profile failed"); + goto Error; + } + + ptr = (cmsUInt32Number*) cmsReadTag(h, SigInt); + if (ptr != NULL) { + + Fail("read tag/context switching failed"); + goto Error; + } + + cmsCloseProfile(h); + ResetFatalError(); + + h = cmsOpenProfileFromMemTHR(cpy2, data, clen); + if (h == NULL) { + Fail("Open profile from mem failed"); + goto Error; + } + + // Get rid of data + free(data); data = NULL; + + ptr = (cmsUInt32Number*) cmsReadTag(h, SigInt); + if (ptr == NULL) { + Fail("Read tag/conext switching failed (2)"); + return 0; + } + + rc = (*ptr == 1234); + + cmsCloseProfile(h); + + cmsDeleteContext(cpy2); + + return rc; + +Error: + + if (h != NULL) cmsCloseProfile(h); + if (ctx != NULL) cmsDeleteContext(ctx); + if (cpy != NULL) cmsDeleteContext(cpy); + if (cpy2 != NULL) cmsDeleteContext(cpy2); + if (data) free(data); + + return 0; +} + +// -------------------------------------------------------------------------------------------------- +// MPE plugin check: +// -------------------------------------------------------------------------------------------------- +#define SigNegateType ((cmsStageSignature)0x6E202020) + +static +void EvaluateNegate(const cmsFloat32Number In[], + cmsFloat32Number Out[], + const cmsStage *mpe) +{ + Out[0] = 1.0f - In[0]; + Out[1] = 1.0f - In[1]; + Out[2] = 1.0f - In[2]; +} + +static +cmsStage* StageAllocNegate(cmsContext ContextID) +{ + return _cmsStageAllocPlaceholder(ContextID, + SigNegateType, 3, 3, EvaluateNegate, + NULL, NULL, NULL); +} + +static +void *Type_negate_Read(struct _cms_typehandler_struct* self, + cmsIOHANDLER* io, + cmsUInt32Number* nItems, + cmsUInt32Number SizeOfTag) +{ + cmsUInt16Number Chans; + if (!_cmsReadUInt16Number(io, &Chans)) return NULL; + if (Chans != 3) return NULL; + + *nItems = 1; + return StageAllocNegate(self -> ContextID); +} + +static +cmsBool Type_negate_Write(struct _cms_typehandler_struct* self, + cmsIOHANDLER* io, + void* Ptr, cmsUInt32Number nItems) +{ + + if (!_cmsWriteUInt16Number(io, 3)) return FALSE; + return TRUE; +} + +static +cmsPluginMultiProcessElement MPEPluginSample = { + + {cmsPluginMagicNumber, 2060, cmsPluginMultiProcessElementSig, NULL}, + + { (cmsTagTypeSignature) SigNegateType, Type_negate_Read, Type_negate_Write, NULL, NULL, NULL } +}; + + +cmsInt32Number CheckMPEPlugin(void) +{ + cmsContext ctx = NULL; + cmsContext cpy = NULL; + cmsContext cpy2 = NULL; + cmsHPROFILE h = NULL; + cmsUInt32Number myTag = 1234; + cmsUInt32Number rc = 0; + char* data = NULL; + cmsUInt32Number clen = 0; + cmsFloat32Number In[3], Out[3]; + cmsPipeline* pipe; + + ctx = WatchDogContext(NULL); + cmsPluginTHR(ctx, &MPEPluginSample); + + cpy = DupContext(ctx, NULL); + cpy2 = DupContext(cpy, NULL); + + cmsDeleteContext(ctx); + cmsDeleteContext(cpy); + + h = cmsCreateProfilePlaceholder(cpy2); + if (h == NULL) { + Fail("Create placeholder failed"); + goto Error; + } + + pipe = cmsPipelineAlloc(cpy2, 3, 3); + cmsPipelineInsertStage(pipe, cmsAT_BEGIN, StageAllocNegate(cpy2)); + + + In[0] = 0.3f; In[1] = 0.2f; In[2] = 0.9f; + cmsPipelineEvalFloat(In, Out, pipe); + + rc = (IsGoodVal("0", Out[0], 1.0-In[0], 0.001) && + IsGoodVal("1", Out[1], 1.0-In[1], 0.001) && + IsGoodVal("2", Out[2], 1.0-In[2], 0.001)); + + if (!rc) { + Fail("Pipeline failed"); + goto Error; + } + + if (!cmsWriteTag(h, cmsSigDToB3Tag, pipe)) { + Fail("Plug-in failed"); + goto Error; + } + + // This cleans the stage as well + cmsPipelineFree(pipe); + + rc = cmsSaveProfileToMem(h, NULL, &clen); + if (!rc) { + Fail("Fetch mem size failed"); + goto Error; + } + + + data = (char*) malloc(clen); + if (data == NULL) { + Fail("malloc failed ?!?"); + goto Error; + } + + + rc = cmsSaveProfileToMem(h, data, &clen); + if (!rc) { + Fail("Save to mem failed"); + goto Error; + } + + cmsCloseProfile(h); + + + cmsSetLogErrorHandler(NULL); + h = cmsOpenProfileFromMem(data, clen); + if (h == NULL) { + Fail("Open profile failed"); + goto Error; + } + + pipe = (cmsPipeline*) cmsReadTag(h, cmsSigDToB3Tag); + if (pipe != NULL) { + + // Unsupported stage, should fail + Fail("read tag/context switching failed"); + goto Error; + } + + cmsCloseProfile(h); + + ResetFatalError(); + + h = cmsOpenProfileFromMemTHR(cpy2, data, clen); + if (h == NULL) { + Fail("Open profile from mem failed"); + goto Error; + } + + // Get rid of data + free(data); data = NULL; + + pipe = (cmsPipeline*) cmsReadTag(h, cmsSigDToB3Tag); + if (pipe == NULL) { + Fail("Read tag/conext switching failed (2)"); + return 0; + } + + // Evaluate for negation + In[0] = 0.3f; In[1] = 0.2f; In[2] = 0.9f; + cmsPipelineEvalFloat(In, Out, pipe); + + rc = (IsGoodVal("0", Out[0], 1.0-In[0], 0.001) && + IsGoodVal("1", Out[1], 1.0-In[1], 0.001) && + IsGoodVal("2", Out[2], 1.0-In[2], 0.001)); + + cmsCloseProfile(h); + + cmsDeleteContext(cpy2); + + return rc; + +Error: + + if (h != NULL) cmsCloseProfile(h); + if (ctx != NULL) cmsDeleteContext(ctx); + if (cpy != NULL) cmsDeleteContext(cpy); + if (cpy2 != NULL) cmsDeleteContext(cpy2); + if (data) free(data); + + return 0; +} + + +// -------------------------------------------------------------------------------------------------- +// Optimization plugin check: +// -------------------------------------------------------------------------------------------------- + +static +void FastEvaluateCurves(register const cmsUInt16Number In[], + register cmsUInt16Number Out[], + register const void* Data) +{ + Out[0] = In[0]; +} + +static +cmsBool MyOptimize(cmsPipeline** Lut, + cmsUInt32Number Intent, + cmsUInt32Number* InputFormat, + cmsUInt32Number* OutputFormat, + cmsUInt32Number* dwFlags) +{ + cmsStage* mpe; + _cmsStageToneCurvesData* Data; + + // Only curves in this LUT? All are identities? + for (mpe = cmsPipelineGetPtrToFirstStage(*Lut); + mpe != NULL; + mpe = cmsStageNext(mpe)) { + + if (cmsStageType(mpe) != cmsSigCurveSetElemType) return FALSE; + + // Check for identity + Data = (_cmsStageToneCurvesData*) cmsStageData(mpe); + if (Data ->nCurves != 1) return FALSE; + if (cmsEstimateGamma(Data->TheCurves[0], 0.1) > 1.0) return FALSE; + + } + + *dwFlags |= cmsFLAGS_NOCACHE; + _cmsPipelineSetOptimizationParameters(*Lut, FastEvaluateCurves, NULL, NULL, NULL); + + return TRUE; +} + +cmsPluginOptimization OptimizationPluginSample = { + + {cmsPluginMagicNumber, 2060, cmsPluginOptimizationSig, NULL}, + MyOptimize +}; + + +cmsInt32Number CheckOptimizationPlugin(void) +{ + cmsContext ctx = WatchDogContext(NULL); + cmsContext cpy; + cmsContext cpy2; + cmsHTRANSFORM xform; + cmsUInt8Number In[]= { 10, 20, 30, 40 }; + cmsUInt8Number Out[4]; + cmsToneCurve* Linear; + cmsHPROFILE h; + int i; + + cmsPluginTHR(ctx, &OptimizationPluginSample); + + cpy = DupContext(ctx, NULL); + cpy2 = DupContext(cpy, NULL); + + Linear = cmsBuildGamma(cpy2, 1.0); + h = cmsCreateLinearizationDeviceLinkTHR(cpy2, cmsSigGrayData, &Linear); + cmsFreeToneCurve(Linear); + + xform = cmsCreateTransformTHR(cpy2, h, TYPE_GRAY_8, h, TYPE_GRAY_8, INTENT_PERCEPTUAL, 0); + cmsCloseProfile(h); + + cmsDoTransform(xform, In, Out, 4); + + cmsDeleteTransform(xform); + cmsDeleteContext(ctx); + cmsDeleteContext(cpy); + cmsDeleteContext(cpy2); + + for (i=0; i < 4; i++) + if (In[i] != Out[i]) return 0; + + return 1; +} + + +// -------------------------------------------------------------------------------------------------- +// Check the intent plug-in +// -------------------------------------------------------------------------------------------------- + +/* + This example creates a new rendering intent, at intent number 300, that is identical to perceptual + intent for all color spaces but gray to gray transforms, in this case it bypasses the data. + Note that it has to clear all occurrences of intent 300 in the intents array to avoid + infinite recursion. +*/ + +#define INTENT_DECEPTIVE 300 + +static +cmsPipeline* MyNewIntent(cmsContext ContextID, + cmsUInt32Number nProfiles, + cmsUInt32Number TheIntents[], + cmsHPROFILE hProfiles[], + cmsBool BPC[], + cmsFloat64Number AdaptationStates[], + cmsUInt32Number dwFlags) +{ + cmsPipeline* Result; + cmsUInt32Number ICCIntents[256]; + cmsUInt32Number i; + + for (i=0; i < nProfiles; i++) + ICCIntents[i] = (TheIntents[i] == INTENT_DECEPTIVE) ? INTENT_PERCEPTUAL : + TheIntents[i]; + + if (cmsGetColorSpace(hProfiles[0]) != cmsSigGrayData || + cmsGetColorSpace(hProfiles[nProfiles-1]) != cmsSigGrayData) + return _cmsDefaultICCintents(ContextID, nProfiles, + ICCIntents, hProfiles, + BPC, AdaptationStates, + dwFlags); + + Result = cmsPipelineAlloc(ContextID, 1, 1); + if (Result == NULL) return NULL; + + cmsPipelineInsertStage(Result, cmsAT_BEGIN, + cmsStageAllocIdentity(ContextID, 1)); + + return Result; +} + +static cmsPluginRenderingIntent IntentPluginSample = { + + {cmsPluginMagicNumber, 2060, cmsPluginRenderingIntentSig, NULL}, + + INTENT_DECEPTIVE, MyNewIntent, "bypass gray to gray rendering intent" +}; + +cmsInt32Number CheckIntentPlugin(void) +{ + cmsContext ctx = WatchDogContext(NULL); + cmsContext cpy; + cmsContext cpy2; + cmsHTRANSFORM xform; + cmsHPROFILE h1, h2; + cmsToneCurve* Linear1; + cmsToneCurve* Linear2; + cmsUInt8Number In[]= { 10, 20, 30, 40 }; + cmsUInt8Number Out[4]; + int i; + + cmsPluginTHR(ctx, &IntentPluginSample); + + cpy = DupContext(ctx, NULL); + cpy2 = DupContext(cpy, NULL); + + Linear1 = cmsBuildGamma(cpy2, 3.0); + Linear2 = cmsBuildGamma(cpy2, 0.1); + h1 = cmsCreateLinearizationDeviceLinkTHR(cpy2, cmsSigGrayData, &Linear1); + h2 = cmsCreateLinearizationDeviceLinkTHR(cpy2, cmsSigGrayData, &Linear2); + + cmsFreeToneCurve(Linear1); + cmsFreeToneCurve(Linear2); + + xform = cmsCreateTransformTHR(cpy2, h1, TYPE_GRAY_8, h2, TYPE_GRAY_8, INTENT_DECEPTIVE, 0); + cmsCloseProfile(h1); cmsCloseProfile(h2); + + cmsDoTransform(xform, In, Out, 4); + + cmsDeleteTransform(xform); + cmsDeleteContext(ctx); + cmsDeleteContext(cpy); + cmsDeleteContext(cpy2); + + for (i=0; i < 4; i++) + if (Out[i] != In[i]) return 0; + + return 1; +} + + +// -------------------------------------------------------------------------------------------------- +// Check the full transform plug-in +// -------------------------------------------------------------------------------------------------- + +// This is a sample intent that only works for gray8 as output, and always returns '42' +static +void TrancendentalTransform(struct _cmstransform_struct * CMM, + const void* InputBuffer, + void* OutputBuffer, + cmsUInt32Number Size, + cmsUInt32Number Stride) +{ + cmsUInt32Number i; + + for (i=0; i < Size; i++) + { + ((cmsUInt8Number*) OutputBuffer)[i] = 0x42; + } + +} + + +cmsBool TransformFactory(_cmsTransformFn* xformPtr, + void** UserData, + _cmsFreeUserDataFn* FreePrivateDataFn, + cmsPipeline** Lut, + cmsUInt32Number* InputFormat, + cmsUInt32Number* OutputFormat, + cmsUInt32Number* dwFlags) + +{ + if (*OutputFormat == TYPE_GRAY_8) + { + // *Lut holds the pipeline to be applied + *xformPtr = TrancendentalTransform; + return TRUE; + } + + return FALSE; +} + + +// The Plug-in entry point +static cmsPluginTransform FullTransformPluginSample = { + + { cmsPluginMagicNumber, 2060, cmsPluginTransformSig, NULL}, + + TransformFactory +}; + +cmsInt32Number CheckTransformPlugin(void) +{ + cmsContext ctx = WatchDogContext(NULL); + cmsContext cpy; + cmsContext cpy2; + cmsHTRANSFORM xform; + cmsUInt8Number In[]= { 10, 20, 30, 40 }; + cmsUInt8Number Out[4]; + cmsToneCurve* Linear; + cmsHPROFILE h; + int i; + + + cmsPluginTHR(ctx, &FullTransformPluginSample); + + cpy = DupContext(ctx, NULL); + cpy2 = DupContext(cpy, NULL); + + Linear = cmsBuildGamma(cpy2, 1.0); + h = cmsCreateLinearizationDeviceLinkTHR(cpy2, cmsSigGrayData, &Linear); + cmsFreeToneCurve(Linear); + + xform = cmsCreateTransformTHR(cpy2, h, TYPE_GRAY_8, h, TYPE_GRAY_8, INTENT_PERCEPTUAL, 0); + cmsCloseProfile(h); + + cmsDoTransform(xform, In, Out, 4); + + + cmsDeleteTransform(xform); + cmsDeleteContext(ctx); + cmsDeleteContext(cpy); + cmsDeleteContext(cpy2); + + for (i=0; i < 4; i++) + if (Out[i] != 0x42) return 0; + + return 1; +} + + +// -------------------------------------------------------------------------------------------------- +// Check the mutex plug-in +// -------------------------------------------------------------------------------------------------- + +typedef struct { + int nlocks; +} MyMtx; + + +static +void* MyMtxCreate(cmsContext id) +{ + MyMtx* mtx = (MyMtx*) _cmsMalloc(id, sizeof(MyMtx)); + mtx ->nlocks = 0; + return mtx; +} + +static +void MyMtxDestroy(cmsContext id, void* mtx) +{ + MyMtx* mtx_ = (MyMtx*) mtx; + + if (mtx_->nlocks != 0) + Die("Locks != 0 when setting free a mutex"); + + _cmsFree(id, mtx); + +} + +static +cmsBool MyMtxLock(cmsContext id, void* mtx) +{ + MyMtx* mtx_ = (MyMtx*) mtx; + mtx_->nlocks++; + + return TRUE; +} + +static +void MyMtxUnlock(cmsContext id, void* mtx) +{ + MyMtx* mtx_ = (MyMtx*) mtx; + mtx_->nlocks--; + +} + + +static cmsPluginMutex MutexPluginSample = { + + { cmsPluginMagicNumber, 2060, cmsPluginMutexSig, NULL}, + + MyMtxCreate, MyMtxDestroy, MyMtxLock, MyMtxUnlock +}; + + +cmsInt32Number CheckMutexPlugin(void) +{ + cmsContext ctx = WatchDogContext(NULL); + cmsContext cpy; + cmsContext cpy2; + cmsHTRANSFORM xform; + cmsUInt8Number In[]= { 10, 20, 30, 40 }; + cmsUInt8Number Out[4]; + cmsToneCurve* Linear; + cmsHPROFILE h; + int i; + + + cmsPluginTHR(ctx, &MutexPluginSample); + + cpy = DupContext(ctx, NULL); + cpy2 = DupContext(cpy, NULL); + + Linear = cmsBuildGamma(cpy2, 1.0); + h = cmsCreateLinearizationDeviceLinkTHR(cpy2, cmsSigGrayData, &Linear); + cmsFreeToneCurve(Linear); + + xform = cmsCreateTransformTHR(cpy2, h, TYPE_GRAY_8, h, TYPE_GRAY_8, INTENT_PERCEPTUAL, 0); + cmsCloseProfile(h); + + cmsDoTransform(xform, In, Out, 4); + + + cmsDeleteTransform(xform); + cmsDeleteContext(ctx); + cmsDeleteContext(cpy); + cmsDeleteContext(cpy2); + + for (i=0; i < 4; i++) + if (Out[i] != In[i]) return 0; + + return 1; +} diff -Nru lcms2-2.5/testbed/testthread.cpp lcms2-2.6/testbed/testthread.cpp --- lcms2-2.5/testbed/testthread.cpp 2013-06-27 16:01:28.000000000 +0000 +++ lcms2-2.6/testbed/testthread.cpp 2014-03-17 16:09:30.000000000 +0000 @@ -1,52 +1,120 @@ #include -#include "lcms.h" +#include "lcms2_plugin.h" -static cmsHPROFILE prof_xyz,prof_rgb; -static cmsHTRANSFORM trans_xyz_to_rgb,trans_rgb_to_xyz; +static cmsContext ctx; +static cmsHPROFILE prof_cmyk, prof_rgb; +static volatile int rc = 0; -static DWORD WINAPI make_trans_xyz_to_rgb(LPVOID lpParameter) + +static +void* MyMtxCreate(cmsContext id) +{ + return (void*) CreateMutex( NULL, FALSE, NULL); +} + +static +void MyMtxDestroy(cmsContext id, void* mtx) +{ + CloseHandle((HANDLE) mtx); +} + +static +cmsBool MyMtxLock(cmsContext id, void* mtx) +{ + WaitForSingleObject((HANDLE) mtx, INFINITE); + return TRUE; +} + +static +void MyMtxUnlock(cmsContext id, void* mtx) +{ + ReleaseMutex((HANDLE) mtx); +} + + +static cmsPluginMutex MutexPluginSample = { + + { cmsPluginMagicNumber, 2060, cmsPluginMutexSig, NULL}, + + MyMtxCreate, MyMtxDestroy, MyMtxLock, MyMtxUnlock +}; + + +static DWORD WINAPI one_thread(LPVOID lpParameter) +{ + int i, j; + cmsUInt8Number rgb[3*1000]; + cmsUInt8Number cmyk[4*1000]; + + Sleep(rand() % 500 ); + cmsHTRANSFORM xform = cmsCreateTransformTHR(ctx, prof_rgb, TYPE_RGB_8, prof_cmyk, TYPE_CMYK_8, 0, 0); + + for (i=0; i < 100000; i++) { + + for (j=0; j < 1000; j++) + { + rgb[j * 3 ] = 189; + rgb[j * 3 + 1] = 100; + rgb[j * 3 + 2] = 75; + } + cmsDoTransform(xform, rgb, cmyk, 1000); + for (j=0; j < 1000; j++) + { + if (cmyk[j * 4 ] != 37 || + cmyk[j * 4 + 1 ] != 188 || + cmyk[j * 4 + 2 ] != 195 || + cmyk[j * 4 + 3 ] != 7) + { + OutputDebugString(L"ERROR\n"); + rc = 1; + } + + } + + } + + cmsDeleteTransform(xform); + + return 0; +} + +int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow) { - trans_xyz_to_rgb = cmsCreateTransform( - prof_xyz,TYPE_XYZ_DBL, - prof_rgb,TYPE_RGB_DBL, - INTENT_ABSOLUTE_COLORIMETRIC,cmsFLAGS_NOTPRECALC); - return 0; -} - -static DWORD WINAPI make_trans_rgb_to_xyz(LPVOID lpParameter) -{ - trans_rgb_to_xyz = cmsCreateTransform( - prof_rgb,TYPE_RGB_DBL, - prof_xyz,TYPE_XYZ_DBL, - INTENT_ABSOLUTE_COLORIMETRIC,cmsFLAGS_NOTPRECALC); - return 0; -} - -int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR -lpCmdLine,int nCmdShow) -{ - prof_xyz = cmsCreateXYZProfile(); - prof_rgb = cmsOpenProfileFromFile("AdobeRGB1998.icc","rb"); -//cmsCreate_sRGBProfile(); - for (int i=0;i<10;++i) - { -#define try_threads -#ifdef try_threads - DWORD threadid; - HANDLE workers[2]; - workers[0] = CreateThread(NULL,0,make_trans_xyz_to_rgb,NULL,0,&threadid); - workers[1] = CreateThread(NULL,0,make_trans_rgb_to_xyz,NULL,0,&threadid); - WaitForMultipleObjects(2,workers,TRUE,INFINITE); - for (unsigned i=0;i<2;++i) - CloseHandle(workers[i]); -#else - make_trans_xyz_to_rgb(0); - make_trans_rgb_to_xyz(0); -#endif - cmsDeleteTransform(trans_xyz_to_rgb); - cmsDeleteTransform(trans_rgb_to_xyz); - } - cmsCloseProfile(prof_rgb); - cmsCloseProfile(prof_xyz); + int i; + cmsContext ctx; + + OutputDebugString(L"Test in progress...\n"); + + ctx = cmsCreateContext(NULL, 0); + + prof_cmyk = cmsOpenProfileFromFileTHR(ctx, "USWebCoatedSWOP.icc", "r"); + prof_rgb = cmsOpenProfileFromFileTHR(ctx, "AdobeRGB1998.icc","r"); + + +#define NWORKERS 10 + + HANDLE workers[NWORKERS]; + + + for (int i=0; i]\n\n"); fprintf(stderr, "flags:\n\n"); @@ -119,6 +119,7 @@ fprintf(stderr, "%cn - Alternate way to set precission, number of CLUT points (CRD only)\n", SW); fprintf(stderr, "\n"); + fprintf(stderr, "If no output file is specified, output goes to stdout.\n\n"); fprintf(stderr, "This program is intended to be a demo of the little cms\n" "engine. Both lcms and this program are freeware. You can\n" "obtain both in source code at http://www.littlecms.com\n" @@ -143,7 +144,7 @@ Buffer = (char*) malloc(n + 1); if (Buffer != NULL) { - cmsGetPostScriptCSA(0, hProfile, Intent, 0, Buffer, n); + cmsGetPostScriptCSA(0, hProfile, Intent, 0, Buffer, (cmsUInt32Number) n); Buffer[n] = 0; fprintf(OutFile, "%s", Buffer); @@ -184,7 +185,7 @@ if (n == 0) return; Buffer = (char*) malloc(n + 1); - cmsGetPostScriptCRD(0, hProfile, Intent, dwFlags, Buffer, n); + cmsGetPostScriptCRD(0, hProfile, Intent, dwFlags, Buffer, (cmsUInt32Number) n); Buffer[n] = 0; fprintf(OutFile, "%s", Buffer); @@ -206,16 +207,14 @@ if (nargs != 0 && nargs != 1) Help(); + if (cInProf == NULL && cOutProf == NULL) + Help(); + if (nargs == 0) OutFile = stdout; else OutFile = fopen(argv[xoptind], "wt"); - - if (cInProf == NULL && cOutProf == NULL) - Help(); - - if (cInProf != NULL) GenerateCSA(); diff -Nru lcms2-2.5/utils/tificc/Makefile.in lcms2-2.6/utils/tificc/Makefile.in --- lcms2-2.5/utils/tificc/Makefile.in 2013-06-27 16:01:28.000000000 +0000 +++ lcms2-2.6/utils/tificc/Makefile.in 2014-03-17 16:09:30.000000000 +0000 @@ -60,7 +60,8 @@ subdir = utils/tificc DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/configure.ac +am__aclocal_m4_deps = $(top_srcdir)/m4/acx_pthread.m4 \ + $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d @@ -175,6 +176,7 @@ LIBTOOL_DEPS = @LIBTOOL_DEPS@ LIB_JPEG = @LIB_JPEG@ LIB_MATH = @LIB_MATH@ +LIB_THREAD = @LIB_THREAD@ LIB_TIFF = @LIB_TIFF@ LIB_ZLIB = @LIB_ZLIB@ LIPO = @LIPO@ @@ -198,6 +200,10 @@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ +PTHREAD_CC = @PTHREAD_CC@ +PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ +PTHREAD_CXX = @PTHREAD_CXX@ +PTHREAD_LIBS = @PTHREAD_LIBS@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ @@ -213,6 +219,7 @@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +acx_pthread_config = @acx_pthread_config@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ diff -Nru lcms2-2.5/utils/tificc/tificc.c lcms2-2.6/utils/tificc/tificc.c --- lcms2-2.5/utils/tificc/tificc.c 2013-06-27 16:01:28.000000000 +0000 +++ lcms2-2.6/utils/tificc/tificc.c 2014-03-17 16:09:30.000000000 +0000 @@ -670,7 +670,7 @@ return; } - EmbedLen = fread(EmbedBuffer, 1, size, f); + EmbedLen = (cmsUInt32Number) fread(EmbedBuffer, 1, (size_t) size, f); if (EmbedLen != size) FatalError("Cannot read %ld bytes to %s", size, ProfileFile); diff -Nru lcms2-2.5/utils/transicc/Makefile.in lcms2-2.6/utils/transicc/Makefile.in --- lcms2-2.5/utils/transicc/Makefile.in 2013-06-27 16:01:28.000000000 +0000 +++ lcms2-2.6/utils/transicc/Makefile.in 2014-03-17 16:09:30.000000000 +0000 @@ -60,7 +60,8 @@ subdir = utils/transicc DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/configure.ac +am__aclocal_m4_deps = $(top_srcdir)/m4/acx_pthread.m4 \ + $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d @@ -146,6 +147,7 @@ LIBTOOL_DEPS = @LIBTOOL_DEPS@ LIB_JPEG = @LIB_JPEG@ LIB_MATH = @LIB_MATH@ +LIB_THREAD = @LIB_THREAD@ LIB_TIFF = @LIB_TIFF@ LIB_ZLIB = @LIB_ZLIB@ LIPO = @LIPO@ @@ -169,6 +171,10 @@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ +PTHREAD_CC = @PTHREAD_CC@ +PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ +PTHREAD_CXX = @PTHREAD_CXX@ +PTHREAD_LIBS = @PTHREAD_LIBS@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ @@ -184,6 +190,7 @@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +acx_pthread_config = @acx_pthread_config@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ diff -Nru lcms2-2.5/utils/transicc/transicc.1 lcms2-2.6/utils/transicc/transicc.1 --- lcms2-2.5/utils/transicc/transicc.1 2013-06-27 16:01:28.000000000 +0000 +++ lcms2-2.6/utils/transicc/transicc.1 2014-03-17 16:09:30.000000000 +0000 @@ -1,5 +1,5 @@ .\"Shiju P. Nair September 30, 2004 -.TH ICCTRANS 1 "September 30, 2004" +.TH TRANSICC 1 "MAY 30, 2011" .SH NAME icctrans - little cms ColorSpace conversion calculator. .SH SYNOPSIS